這次我們來處理一下 解析 css/sass 的需求
首先需要兩個 loader
yarn add style-loader css-loader --dev
css-loader 作用是使你能夠使用類似 @import 和 url(...) 的方法實(shí)現(xiàn) require 的功能
style-loader 會生成一個內(nèi)容為最終解析完的 css 代碼的 style 標(biāo)簽,放到head標(biāo)簽里
簡單來講, css-loader 加載 css 文件, style-loader 使用 <style> 將 css-loader 內(nèi)部樣式注入到我們的 HTML 頁面
修改 webpack.config.js 文件
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: './src/app.jsx',
output: {
path: path.join(__dirname, 'dist'),
filename: 'app.js'
},
module: {
rules: [
{
test: /\.jsx$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader',
options: {
presets: ['env', 'es2015', 'react']
}
}
},
+ {
+ test: /\.css$/,
+ use: [
+ 'style-loader',
+ 'css-loader'
+ ]
+ }
]
},
plugins: [
new HtmlWebpackPlugin({
title: 'MY-WEBPACK',
template: './src/index.html'
})
]
};
也注意一下, use 里面所使用的 loader 執(zhí)行順序是從右往左, 所以這里我們會先用 css-loader 解析 css 文件, 然后再用 style-loader 把解析后的 css 文件注入到 html 中
新建一個 ./src/index.css 文件
#app {
color: red;
}
修改 app.jsx
import React from 'react';
import ReactDOM from 'react-dom';
+ import './index.css'
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('app')
);
到了這一步實(shí)際就完成了 css 的解析, 但是這里有個很大的問題
我們看下 css 被解析成了什么 (在 dist/app.js 里)
.push([e.i,"#app {\r\n color: red;\r\n}\r\n",""])}
上面這段我們可以看出來, css 被解析成了一段 js 然后直接做了一個 push 的動作
依據(jù)頁面的加載順序, 這段 css 其實(shí)會等所有的 js 都執(zhí)行完才會進(jìn)行渲染, 在實(shí)際的表現(xiàn)中我們的頁面會有一個白屏或是無樣式期, 然后才渲染成最后我們所期望的表象, 這很明顯不是我們所期望的結(jié)果
處理這個問題, 首先需要這個插件
yarn add extract-text-webpack-plugin --dev
它會將所有的入口 chunk(entry chunks)中引用的 *.css畦贸,移動到獨(dú)立分離的 CSS 文件殴蓬。因此松邪,你的樣式將不再內(nèi)嵌到 JS bundle 中,而是會放到一個單獨(dú)的 CSS 文件(即 index.css)當(dāng)中怠苔。 如果你的樣式文件大小較大曲掰,這會做更快提前加載,因?yàn)?CSS bundle 會跟 JS bundle 并行加載男杈。
修改一下 webpack.config.js 文件
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
+ const ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
entry: './src/app.jsx',
output: {
path: path.join(__dirname, 'dist'),
filename: 'app.js'
},
module: {
rules: [
{
test: /\.jsx$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader',
options: {
presets: ['env', 'es2015', 'react']
}
}
},
{
test: /\.css$/,
+ use: ExtractTextPlugin.extract({
+ fallback: "style-loader",
+ use: "css-loader"
+ })
}
]
},
plugins: [
new HtmlWebpackPlugin({
title: 'MY-WEBPACK',
template: './src/index.html'
}),
+ new ExtractTextPlugin("index.css"),
]
};
use 里的修改看起來奇怪, 但是作用還是先執(zhí)行 css-loader 再執(zhí)行 style-loader
plugins 里我們構(gòu)造 ExtractTextPlugin 實(shí)例的時候傳入了 index.css 作為參數(shù), 作用是指定打包后的 css bundle 名
然后可以重新指令運(yùn)行了
node_modules./bin/webpack
但是這里可能會報(bào)錯
Error: Chunk.entrypoints: Use Chunks.groupsIterable and filter by instanceof Entrypoint instead at Chunk.get(...)
解決方案是
yarn add extract-text-webpack-plugin@next --dev
這個問題是因?yàn)?extract-text-webpack-plugin 目前還沒有 webpack4 版本
有興趣可以去這個網(wǎng)址看看 有一些有意思的討論 https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/701
重新指令運(yùn)行打包以后 dist 文件夾里就會出現(xiàn) index.css 文件了, 我們在 index.html 里也會看到 style 標(biāo)簽引入了這個 css 文件
css 就搞定了 接著是 sass (less 我就不寫了 沒啥區(qū)別)
安裝
yarn add sass-loader node-sass --dev
node-sass 是一定要裝的, 它是 sass-loader 的依賴
但是 node-sass 二進(jìn)制文件的下載源在墻外, 所以你可能需要翻墻 或者換 yarn 的下載源等等方法 這里不細(xì)寫了
修改 webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
entry: './src/app.jsx',
output: {
path: path.join(__dirname, 'dist'),
filename: 'app.js'
},
module: {
rules: [
{
test: /\.jsx$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader',
options: {
presets: ['env', 'es2015', 'react']
}
}
},
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader"
})
},
+ {
+ test: /\.scss$/,
+ use: ExtractTextPlugin.extract({
+ fallback: 'style-loader',
+ use: ['css-loader', 'sass-loader']
+ })
+ }
]
},
plugins: [
new HtmlWebpackPlugin({
title: 'MY-WEBPACK',
template: './src/index.html'
}),
new ExtractTextPlugin("index.css"),
]
};
修改 app.jsx
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
+ import './index.scss';
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('app')
);
新增 ./src/index.scss
body {
background-color: black;
#app {
font-size: 30px;
}
}
然后打包 你會看到 src/index.scss 和 src/index.css 的內(nèi)容都被解析后丟進(jìn)了 dist/index.css 文件里
完
接著處理下 圖片和字體