虽然webpack4不支持 ExtractTextWebpackPlugin
插件,可是咱们能够使用 mini-css-extract-plugin
来实现把 css 提取为单独的文件。javascript
相比 ExtractTextWebpackPlugin,mini-css-extract-plugin 有以下优势:css
但目前 mini-css-extract-plugin 不支持HMR。html
详情见 mini-css-extract-plugin
官方文档:github.com/webpack-con…java
mini-css-extract-plugin
的做用在于可以将全部的入口 chunk (entry chunks) 中引用的 *.css,移动到独立分离的 CSS 文件中。webpack
所以,你的样式将再也不内嵌到 JS bundle 中,而是会放到一个单独的 CSS 文件(好比 styles.css)当中。git
若是你的样式文件大小较大,这会作更快提早加载,由于 CSS bundle 会跟 JS bundle 并行加载。github
使用 mini-css-extract-plugin
优势:web
缺点在于:npm
虽然
file-loader
也能够把 css 单独提取到 css 文件,可是没法合并多个css文件segmentfault
注意css的同步加载仍是异步加载的引用方式:
同步加载:import './style2.css';
异步加载:import('./style2.css');
两种的打包结果是不同的
HtmlWebpackPlugin 简化了 HTML 文件的建立,以便为你的 webpack 包提供服务。这对于在文件名中包含每次会随着编译而发生变化哈希的 webpack bundle 尤为有用。 你可让插件为你生成一个HTML文件,使用 lodash 模板提供你本身的模板,或使用你本身的 loader。
(注意:mini-css-extract-plugin 依赖于 webpack,所以须要在项目下安装 webpack)
npm install -D webpack
npm install -D css-loader
npm install -D mini-css-extract-plugin
npm install -D html-webpack-plugin
复制代码
// `--` 表明目录, `-` 表明文件
--demo14
--src
--module1(同步模块)
-module1.css
-module1.js
--module2(异步模块)
-module2.css
-module2.js
--styles
-async-style.css
-common.css
-app.js
--vendor(第三方包)
-vendor.css
-vendor.js
-index.html
s-webpack.config.js
复制代码
src/module1/module1.css
body {
color: black;
}
复制代码
src/module1/module1.js
import './module1.css';
console.log('这里是同步module1');
复制代码
src/module2/module2.css
body {
font-size: 100px;
}
复制代码
src/module2/module2.js
import './module2.css';
console.log('这里是异步module2');
复制代码
src/styles/async-style.css
body {
background-color: red;
}
复制代码
src/styles/common.css
body {
font-family: monospace, "Microsoft Yahei", "微软雅黑", STXihei, "华文细黑";
}
复制代码
vendor/vendor.css
/* 第三方包css */
body {
border: 1px solid black;
}
复制代码
vendor/vendor.js
// 这里假设vendor为第三方包
import './vendor.css';
console.log('这里是第三方依赖包');
复制代码
src/app.js
// 同步加载common.css
import './styles/common.css';
// 同步加载module1.js
import * as module1 from './module1/module1';
// 同步加载第三方包vendor.js
import * as vendor from '../vendor/vendor';
window.addEventListener('click', function () {
// 异步加载module2.js
import(/* webpackChunkName: 'module2'*/ './module2/module2').then(_ => {
console.log('加载异步module2成功');
});
// async-style.css
import(/* webpackChunkName: 'async-style'*/'./styles/async-style.css').then(_ => {
console.log('加载异步async-style.css成功');
});
});
复制代码
webpack.config.js
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
mode: 'production' || 'development' || 'production',
entry: {
app: "./src/app.js"
},
output: {
publicPath: __dirname + "/dist/", // 打包后资源文件的引用会基于此路径
path: path.resolve(__dirname, "dist"), // 打包后的输出目录
filename: "[id].[name].[chunkhash:8].bundle.js", // 在development模式下,id为name
chunkFilename: "[id].[name].[chunkhash:8].chunk.js"
},
module: {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
]
}
]
},
optimization: {
runtimeChunk: "single", // webpack运行时代码单独提取为一个包
splitChunks: {
cacheGroups: {
async: { // 为异步代码打成一个公共包(在app.js修改一下代码,从新打包,不影响此包hash)
name: 'async',
chunks: 'async', // 为异步代码打包
minChunks: 1,
minSize: 0
},
vendors: { // 因为第三方代码变更比较小,因此把全部第三方单独打包,利于缓存(在app.js修改一下代码,从新打包,不影响此包hash)
test: /[\\/]vendor[\\/]/,
name: 'vendor',
chunks: 'all', // 设置为all
minChunks: 1,
minSize: 0// 这里为了演示,设置为0以知足打包条件
}
}
}
},
plugins: [
new HtmlWebpackPlugin({ // 自动生成html,而且自动导入全部依赖同步包
filename: "index.html",
template: "./index.html",
minify: {
// collapseWhitespace: true // 压缩
}
}),
new MiniCssExtractPlugin({
filename: "[id].[name].[chunkhash:8].css",
chunkFilename: "[id].[name].[chunkhash:8].css"
})
]
}
复制代码
(默认你已经安装了全局 webpack 以及 webpack-cli )
webpack
复制代码
输出结果:
0.async.512ec03b.chunk.js
0.async.512ec03b.css
1.app.4cfbacec.chunk.js
1.app.4cfbacec.css
2.runtime.0d1b9de2.bundle.js
3.vendor.c1185876.chunk.js
3.vendor.c1185876.css
index.html
复制代码
在浏览器运行 dist/index.html 查看效果。
demo 代码地址: github.com/SimpleCodeC…
仓库代码地址(及目录): github.com/SimpleCodeC…