上次体验了 Webpack4 的零配置,现在进行 Webpack4 开发环境搭建。
本地安装依赖#
npm install webpack webpack-cli --save-dev创建配置文件#
touch webpack.config.js为了方便调试,在package.json中编写脚本命令
{
"scripts": {
"dev": "webpack --mode development",
"build": "webpack --mode production"
}
}配置好后就可以根据开发环境和生产环境,使用npm run dev和npm run build命令打包文件。
配置入口和输出#
// webpack.config.js
const path = require("path");
const config = {
// 入口
entry: "./src/main.js", // 入口文件
// 输出
output: {
path: path.join(__dirname, "/dist"), // 输出路径
filename: "js/[name]-[chunkhash:8].js", // 输出文件的名字
// publicPath: './', html引用的路径前面会加上'./'
},
};测试:在index.js输入代码,运行npm run dev命令, 看下是否打包成功。
可以把打包后的文件引用到html文件中去看看效果。不过每次都要手动引用,会发现很麻烦。
<script src="./dist/js/main-xxxxxxxx.js"></script>下面需要使用html-webpack-plugin插件,自动生成html文件。
配置插件html-webpack-plugin#
npm install html-webpack-plugin --save-dev // 本地安装// webpack.config.js
const HtmlWebpackPlugin = require("html-webpack-plugin");
const config = {
// ...
plugins: [new HtmlWebpackPlugin()],
};运行npm run dev试试,是否发现在 dist 文件夹下面生成了一个index.html文件,
生成的 html 还自动引用了打包后的 js 文件呢!这个插件还可以配置很多参数,看下面代码:
// webpack.config.js
const HtmlWebpackPlugin = require("html-webpack-plugin");
const config = {
plugins: [
new HtmlWebpackPlugin({
template: "index.html", // 参照模板
filename: "index.html", // 输入名称
inject: true, // 静态文件是否注入和注入的位置('head','body')
title: "webpack-demo", // 自定义标题
date: new Date(), // 自定义时间
// minify: { // 压缩html
// collapseWhitespace: true, // 去掉不必要的空格
// removeComments: true, // 去掉注释
// removeAttributeQuotes: true // 去掉属性值的引号
// }
}),
],
};自定义标题和时间,需要在模板里配置相应的模板语言才能实现,这里以ejs模板语言为例
<!-- index.html -->
<head>
<meta charset="UTF-8" />
<title><%= HtmlWebpackPlugin.options.title %></title>
</head>
<body>
<%= HtmlWebpackPlugin.options.date %>
</body>也可以自定义js注入
// webpack.config.js
const HtmlWebpackPlugin = require("html-webpack-plugin");
const config = {
plugins: [
new HtmlWebpackPlugin({
// ...
inject: false,
}),
],
};ejs
<body>
<script src="<%= htmlWebpackPlugin.files.chunks.main.entry %>"></script>
</body>ps:上面的属性HtmlWebpackPlugin.files.chunks.main.entry是怎么得来的呢?
其实可以遍历HtmlWebpackPlugin这个插件,可查询到一系列参数和属性,
这对于配置和学习,非常有帮助,代码如下:
<body>
<% for (key in HtmlWebpackPlugin.options) { %> <%= key %>: <%=
JSON.stringify(HtmlWebpackPlugin.options[key]) %> <% } %> <% for (key in
HtmlWebpackPlugin.files) { %> <%= key %>: <%=
JSON.stringify(HtmlWebpackPlugin.files[key]) %> <% } %>
</body>配置 Loader#
Webpack 默认只能解析js文件(ES5), 解析其他的文件比如.css,ES6,.vue,.styl等文件需要配置相应的 Loader。
解析 CSS#
npm install css-loader style-loader --save-dev # 下载解析的 Loader// webpack.config.js
const config = {
module: {
// 规则
rules: [
{
test: /\.css$/, // 正则表达式匹配
use: ["style-loader", "css-loader"], // 相关loader
},
],
},
};说明:css-loader是解析css文件的,style-loader是把css文件注入到html中的。
如果需要在打包后的 CSS 里一些 CSS3 属性前自动加上一些兼容性的前缀的话,还需要下载postcss-loader和autoprefixer这两个库。
npm install postcss-loader autoprefixer --save-dev # 下载相关依赖// webpack.config.js
// ...
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: { // 选项参数配置
ident: 'postcss',
plugins: [
require('autoprefixer')({
browsers: ['last 5 version']
})
]
}
}
]
}
// ...注意postcss-loader位置放在最后面,表示最先使用这个 Loader 来解析css文件。
如果你是用了 CSS 的预处理器,比如Less,Sass/Scss,Stylus,需要下载对应的 Loader。
比如我比较喜欢使用的是Stylus预处理器,需要安装下面的依赖
npm install stylus-loader stylus --save-dev # 下载相关依赖注意:stylus是stylus-loaderLoader 的依赖,需要一起下载
// webpack.config.js
// ...
{
test: /\.styl$/,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: [
require('autoprefixer')({
browsers: ['last 5 version']
})
]
}
},
'stylus-loader'
]
}
// ...注意stylus-loader位置放在最后面,表示最先使用这个 Loader 来解析css文件。
解析 ES6 语法的js文件#
npm install babel-loader babel-core babel-preset-env --save-dev 下载loader和相关依赖// webpack.config.js
{
test: /\.js$/,
include: /src/, // 只解析src目录
// exclude: /dist/, // 解析不包含dist目录
use: {
loader: "babel-loader",
options: {
"presets": ["env"]
}
},
},解析图片文件#
npm install url-loader file-loader --save-dev # 下载相关依赖// webpack.config.js
{
test: /\.(git|png|jpe?g|svg)$/,
loader: 'url-loader',
options: {
limit: 10000
}
}说明:limit: 10000表示解析的文件小于 10000 字节时使用base64格式转码,而大于 10000 字节时使用file-loaderLoader 解析。
其他 Loader#
// webpack.config.js
{
test: /\.html$/,
loader: 'html-loader'
}
{
test: /\.vue$/,
loader: 'vue-loader'
}其他的 Loader,匹配相应的格式,在下载相应的 Loader 解析就行了。
使用 Vue 框架的话,需要使用vue-loader来解析.vue文件,当然你也可以使用官方提供的脚手架vue-cli来搭建项目。
配置webpack-dev-server#
webpack-dev-server可以开启一个本地服务器,方便我们开发。
安装webpack-dev-server
npm install webpack-dev-server --save-dev # 本地安装编写脚本命令
{
"scripts": {
"server": "webpack-dev-server"
}
}配置webpack.config.js文件
// webpack.config.js
config.devServer = {
contentBase: path.resolve(__dirname + "/dist"), // 加载页面目录
inline: true, // 内联模式
hot: true, // 是否显示热模块替换记录,console会显示logger
host: "0.0.0.0", // 地址
port: 9000, // 端口
};webpack-dev-server有一个非常强大的功能 HMR,叫热模块替换,也叫热更替。就是你修改了文件(比如 css 样式,js 代码)后,不用去刷新页面,HMR 会自动更新修改的模块,在网页直接显示出来,非常方便快捷,提高开发效率。
需要配置热模块替换插件,热模块替换才会生效。
// webpack.config.js
const webpack = require("webpack");
const config = {
// ...
plugins: [
// ...
new webpack.HotModuleReplacementPlugin(),
],
};注意:每次修改 Webpack 的配置文件后,都需要重新执行编译命令。
我们开发时经常需要去后台取数据,但是有时候后端没弄好,我们可以自己去 mock 数据,webpack-dev-server也可以提供这个功能,它可以启动一个服务器模拟后端数据。
我们先去创建一段 json 数据,比如:
{
"name": "hale",
"gender": "male",
"lang": ["javascript", "python"]
}然后配置服务:
const data = require("./data.json"); // 先导入 json 数据
config.devServer = {
before(app) {
app.get("/api/data", function (req, res) {
res.json({
errno: 0, // 自定义一个状态码,方便后面取数据时判断是否成功
data: data, // 赋值
});
});
},
// ...
};npm run server再次启动devServer时,在浏览器地址栏输入127.0.0.1:9000/api/data,可以查看到 json 数据已经显示出来,后面直接通过访问这个 URL 就可以获取数据了。
webpack 常用插件#
Webpack 除了上面列举的插件外,还有一些插件也非常好用,下面列举几个:
// webpack.config.js
const webpack = require("webpack");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const OptimizeCSSPlugin = require("optimize-css-assets-webpack-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const config = {
// ...
plugins: [
// ...
new webpack.NamedModulesPlugin(), // 显示热更新模块的名称
new webpack.NoErrorsPlugin(), // 不显示错误插件
new ExtractTextPlugin({
// 抽离css样式,还需要在loader下配置,请参考相关文档
filename: "css/[name]-[contenthash].css", // 重命名
allChunks: true,
}),
new OptimizeCSSPlugin(), // 压缩分离出来的css
new CopyWebpackPlugin([
{
// 拷贝文件
from: path.join(__dirname, "./static"),
to: path.join(__dirname, "./dist/static"),
ignore: [".*"],
},
]),
],
};上面列举了几个常用的插件,这些插件都需要安装后才能使用。有的插件需要下载最新版才能在 Webpack4 中正常使用,插件的参数需要根据实际开发来配置,请查看插件的文档。另外一些未例举的插件在 Webpack4 有改动或者删除了,请查看插件的迁移文档。
补充 [2018.6.30]#
1.mode设置为development时,会将process.env.NODE_ENV的值设为development,并且提供了一些开发环境的默认配置,比如启用NamedChunksPlugin和NamedModulesPlugin插件等。
2.model设置为production时,会将process.env.NODE_ENV的值设为production,并且提供了一些生产环境的默认配置,比如启用NoEmitOnErrorsPlugin插件等。
-
提取 CSS 文件的插件
extract-text-webpack-plugin在 Webpack4 中被弃用,需要使用mini-css-extract-plugin库。 -
提取公共代码的插件
CommonsChunkPlugin在 Webpack4 中被弃用,改为配置optimization.splitChunks和optimization.runtimeChunk属性。
总结#
Webpack 是目前最流行的前端工程化工具之一,本文讲的都是一些入门的粗浅知识,以后还会补充一些高级内容。
可参考我搭建的 Vue 开发环境,比文中要详细很多,并且区分开发环境和生产环境,另外还有eslint等配置。
如需了解vue-cli2的关于 Webpack3 的配置,请查看vue-cli2-webpack-comment,有较详细的注释(个人理解)。
最后,如果需要更加深入学习了解 Webpack,请查看官方文档,建议查看英文文档,里面有最新的内容。