ロードされたファイルの内容を、その名前に選択されたテーマのタイトルを持つ兄弟の内容で追加または置換できるローダーを作成しました。
TL; DR
- はローダーを使用してファイルを作成します。
- webpack設定で使用します。
- THEME = <themeName> evironmentでwebpackを実行します。
テーマloader.js
const fs = require('fs');
const loaderUtils = require('loader-utils');
module.exports = function (mainData) {
const options = loaderUtils.getOptions(this);
let themeName = options.theme;
let mode = options.mode;
if (themeName) {
// default mode
if (!Object.keys(transform).includes(mode)) {
mode = 'replace';
}
// fileName.suffix.ext -> fileName.suffix.themeName.ext
const themeAssetPath = this.resourcePath.replace(/\.([^\.]*)$/, `.${themeName}.$1`);
const callback = this.async();
// for HMR to work
this.addDependency(themeAssetPath);
fs.readFile(themeAssetPath, 'utf8', (err, themeData) => {
if (!err) {
callback(null, transform[mode](mainData, themeData));
} else if (err.code === 'ENOENT') {
// don't worry! if it's not here then it's not needed
callback(null, mainData);
} else {
callback(err);
}
});
} else {
return mainData;
}
};
const transform = {
// concat theme file with main file
concat: (mainData, themeData) => mainData + '\n' + themeData,
// replace main file with theme file
replace: (mainData, themeData) => themeData
};
この手作りローダ使用する試料片webpack.config.jsたとえば
resolveLoader: {
modules: [
paths.libs, // ./node_modules
paths.config // this is where our custom loader sits
]
},
module: {
rules: [
// component styles
{
test: /\.css$/,
include: path.join(paths.src, 'app'),
use: [
'raw-loader',
// search for a themed one and append it to main file if found
{
loader: 'theme-loader',
options: {
theme: process.env.THEME,
mode: 'concat'
}
}
]
},
// angular templates — search for a themed one and use it if found
{
test: /\.html$/,
use: ['raw-loader',
{
loader: 'theme-loader',
options: {
theme: process.env.THEME,
mode: 'replace'
}
}
]
}
]
}
をapp.component.css:
:host {
background: #f0f0f0;
color: #333333;
padding: 1rem 2rem;
display: flex;
flex-direction: column;
flex: 1;
justify-content: center;
}
nav {
/* ... */
/* something about nav element */
/* ... */
}
header {
/* ... */
/* pile of styles for header */
/* ... */
}
フレックスとパッディングのスタッフをすべて変更する必要はなく、navとヘッダーに独自の背景とフォントの色設定がない場合もあります。つまり、ホスト要素のスタイルをオーバーライドするだけです。暗いに設定した環境変数をテーマにした
:host {
background: #222222;
color: #e0e0e0;
}
我々の実行のWebPACK:私たちはapp.component.dark.cssを作成します。ローダーが処理する要求を受け取りましたapp.component.css、app.component.dark.cssおよびvoilaをロードしようとしています。テーマのCSSは結果ファイルの末尾に追加されます。競合する複数のセレクタが同じ重要性と特異性を持っている場合、そのためカスケードの、
は、...後でルールは以前のルール(MDN)に勝つだろう。
HTMLの場合、このような方法はありません。だから我々は完全にテンプレートを書き直さなければならないでしょう。うまくいけば、それほど頻繁に行う必要はありません。私のケースでは、cutomerのブランド要求に合わせてヘッダーやフッターのように変更したいと思っていました。
これは初めてのWebpackローダーの作成でした。問題がある場合はコメントを残してください。
アセットを交換して助けてくれました。ローダーがデフォルトローダーで動作するようにローダーを無効にする必要がありました。 (行末問題) – feskr