今回は、webpack スタイルの読み込みの詳細な分析と、webpack スタイルの読み込みの注意点について説明します。以下は実際のケースです。見てみましょう。
CSS をロードするには、css-loader と style-loader が必要です。css-loader は @import と URL を通常の ES6 インポートに処理します。@import が外部リソースを指している場合、css-loader はそれをスキップして内部のみをインポートします。リソースが処理を行います。 css-loader の処理後、style-loader は出力 CSS をパッケージ化ファイルに挿入します。 CSS はデフォルトでインライン モードになり、HMR インターフェイスを実装します。ただし、インラインは運用環境には適していません (すべての出力がページ上にあります)。また、extracttextplugin を使用して別の CSS ファイルを生成する必要がありますが、最初に段階的に実行してみましょう。
1、スタイルパッケージ化
1. css-loader、style-loaderをインストールします
npm install css-loader style-loader --save-dev
2. webpack.config.jsを変更して第1レベルの子ノードを追加します
module:{ rules:[{ test:/\.css$/, use: ['style-loader', 'css-loader'], }] },
test rules .css ファイルと一致します。使用時の実行順序は右から左です。ローダーの実行はパイプラインのように継続的に行われ、最初に css-loader、次に style-loader と続きます。ローダー: ['style-loader', 'css-loader'] は、styleloader(cssloader(input)) として理解できます。
3. スタイルを追加します
app/mian.css
body { background: cornsilk; }
次に、index.js に
import './main.css';
を導入し、npm start を実行して http://localhost:8080/ で開きます
今回は、ページに背景色が表示され、ヘッダーにスタイルが書き込まれていることがわかります。このとき、色を変更すると、インターフェイスが更新されずに更新されます。これは、前の HMR の効果です。セクション。
スタイルも webpackHotUpdate メソッドを通じて更新されます。
2. 負荷を減らす
まず、less-loader
npm install less less-loader --save-dev
をインストールし、次に設定ファイルを変更します:
module:{ rules:[{ test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'], }] },
次に、less ファイルを作成します。 less.less
@base: #f938ab; .box-shadow(@style, @c) when (iscolor(@c)) { -webkit-box-shadow: @style @c; box-shadow: @style @c; } .box-shadow(@style, @alpha: 50%) when (isnumber(@alpha)) { .box-shadow(@style, rgba(0, 0, 0, @alpha)); } .box { color: saturate(@base, 5%); border-color: lighten(@base, 30%); p { .box-shadow(0 0 5px, 30%) } } body { background: cornsilk; }
index.jsを変更します
import './less.less'; import component from './component'; var ele=document.createElement("p"); ele.innerHTML="this is an box"; ele.className="box"; document.body.appendChild(ele); let demoComponent=component(); document.body.appendChild(demoComponent);
その効果は次のとおりです:
lessを使用する場合、インポートはlessファイルのみであることに注意してください。今回は main.css をインポートするとエラーが報告されます。このセクションでは、less の簡単なデモを示します。これは他のスタイルのプリプロセッサにも当てはまります。以下の内容は引き続き css に基づいています。
3. CSS スコープと CSS モジュールを理解する
一般的に、CSS のスコープはマスター ページに複数のスタイル ファイルを追加することが多く、後のスタイル ファイルは前のスタイル ファイルを上書きします。多くの場合、デバッグに問題が発生します。 CSS モジュールでは、インポートを通じてローカル スコープが導入されます。これにより、名前空間の競合が回避されます。 Webpack の css-loader は CSS モジュールをサポートしています。まず、いくつかの例を見てみましょう。まず設定で有効にします (最初に HMR をオフにします):
module:{ rules:[{ test:/\.css$/, use: ['style-loader', { loader: 'css-loader', options: { modules: true,//让css-loader支持Css Modules。 }, },],
次に、新しいスタイル (main.css) を定義します:
body { background: cornsilk; } .redButton { background: red;color:yellow; }
コンポーネントにスタイルを追加し、最初に main.css を導入します。
import styles from './main.css'; export default function () { var element = document.createElement('h1'); element.className=styles.redButton; element.innerHTML = 'Hello webpack'; return element; }
この時点で、インターフェイスが変更されたことがわかります。
右側で生成されたスタイルを見てください。スタイル名が変更されています。全体の処理を振り返ると、main.css内の各クラス名がモジュールになったことに相当し、js上でモジュールのように取得できます。しかし、なぜ要素に値を直接割り当てることができないのに、なぜそれをインポートする必要があるのかと考えているかもしれません。これは良い質問です。別のスタイル ファイルに同じ名前の別のスタイル
クラスを追加しましょう
other.css
.redButton { background:rebeccapurple;color:snow; }
これには .redbutton クラスもあります (ただし、効果は紫色です)。 .js p 要素を作成し、それに redbutton スタイルを追加します。
すごい効果をもう一度見てください
上面这个图说明了两问题,一个是我们在index.js中引入了2个样式文件,在index页面就输出了两个style,这让人有点不爽,但我们后面再解决。另外一个就是虽然两个样式文件中都有redButton这个类,但是这两者还是保持独立的。这样就避免了命名空间的相互干扰。如果你这个时候直接赋值
element.className="redButton";
这样是获取不到样式的。直接对元素的样式默认是全局的。
全局样式
如果想让某个样式是全局的。可以通过:global来包住。
other.css
:global(.redButton) { background:rebeccapurple;color:snow; border: 1px solid red; }
main.css
:global(.redButton) { background: red;color:yellow; }
这个时候redbutton这两个样式就会合并。需要直接通过样式名来获取。
element.className="redButton";
组合样式
我们再修改other.css,创建一个shadowButton 样式,内部通过composes组合redbutton类。
.redButton { background:rebeccapurple;color:snow; border: 1px solid red; } .shadowButton{ composes:redButton; box-shadow: 0 0 15px black; }
修改index.js:
var ele=document.createElement("p"); ele.innerHTML="this is an shadowButton button"; console.log(styles); ele.className=styles.shadowButton; document.body.appendChild(ele);
看一下是什么效果:
日志打印出来的是styles对象,它包含了两个类名。可以看见shadowButton是由两个类名组合而成的。p的class和下面的对应。
四、输出样式文件
css嵌在页面里面不是我们想要的,我们希望能够分离,公共的部分能够分开。extracttextplugin 可以将多个css合成一个文件,但是它不支持HMR(直接注释掉hotOnly:true)。用在生产环境挺好的
npm install extract-text-webpack-plugin --save-dev
先安装extracttextplugin这个插件,然后再webpack.config.js中进行配置:
const ExtractTextPlugin = require('extract-text-webpack-plugin'); const extractTxtplugin = new ExtractTextPlugin({ filename: '[name].[contenthash:8].css', }); const commonConfig={ entry: { app: PATHS.app, }, output: { path: PATHS.build, filename: '[name].js', }, module:{ rules:[{ test:/\.css$/, use:extractTxtplugin.extract({ use:'css-loader', fallback: 'style-loader', }) }]}, plugins: [ new HtmlWebpackPlugin({ title: 'Webpack demo', }), extractTxtplugin ], }
一开始看到这个配置,让人有点懵。首先看fileName,表示最后输出的文件按照这个格式'[name].[contenthash:8].css',name默认是对应的文件夹名称(这里是app),contenthash会返回特定内容的hash值,而:8表示取前8位。当然你也可以按照其他的格式写,比如直接命名:
new ExtractTextPlugin('style.css')
而ExtractTextPlugin.extract本身是一个loader。fallback:'style-loader'的意思但有css没有被提取(外部的css)的时候就用style-loader来处理。注意到现在我们的index.js如下:
import './main.css'; import styles from './other.css'; import component from './component'; var ele=document.createElement("p"); ele.innerHTML="this is an box"; ele.className=styles.shadowButton; document.body.appendChild(ele); let demoComponent=component(); document.body.appendChild(demoComponent); //HMR 接口 if(module.hot){ module.hot.accept('./component',()=>{ const nextComponent=component(); document.body.replaceChild(nextComponent,demoComponent); demoComponent=nextComponent; }) }
引入了两个css文件。
这个时候我们执行 npm run build
再看文件夹得到一个样式文件。(如果不想看到日志可以直接npm build)
但是我们在第三部分使用了CSS Modules,发现other.css的样式没有打包进来。所以,我们的webpack.config.js还要修改:
module:{ rules:[{ test:/\.css$/, use:extractTxtplugin.extract({ use:[ { loader: 'css-loader', options: { modules: true, }, }], fallback: 'style-loader', }) }]},
再次build。
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
以上がWebpack スタイルの読み込みの詳細な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。