Webpack 4 教程:从0配置到生产模式
webpack 4 问世了!除了大幅度的性能提升,而且增加了零配置的默认设置。
目录
- webpack 4 ,零配置的模块打包工具
- webpack 4:零配置开始
- Webpack 4: 生产和开发模式
- webpack 4:覆盖默认的入口/出口文件
- webpack 4:用 Babel 7 转译 ES6 的 js 代码
- webpack 4:在 webpack 4 中配置 React
- webpack 4:HTML 插件
- webpack 4: 提取 CSS 到文件中
- webpack 4:webpack dev server
webpack 4 ,零配置的模块打包工具
webpack 是一个强力和有着很多独特功能的工具,但是他的一大痛点在于他的配置文件
如果是大中型项目我添加配置文件没什么大问题,有时候也是必须的。但是有时候就随便弄个项目来玩玩,还要添加配置文件,嗯,很不友好。
这也是 Parcel
之所以受欢迎的原因
现在的好消息是 webpack 4 默认也不需要配置文件了!撒花撒花~ ?
webpack 4:零配置开始
创建一个目录然后进入
mkdir webpack-4-quickstart && cd $_
初始化 package.json
:
npm init -y
安装 webpack4:
npm i webpack --save-dev
还需要安装另外一个包:webpack-cli
npm i webpack-cli --save-dev
然后打开 package.json 添加构建脚本:
"scripts": {
"build": "webpack"
}
试着运行
npm run build
然后我们看到
ERROR in Entry module not found: Error: Can't resolve './src' in '~/webpack-4-quickstart'
OJBK! 没有找到入口文件。
简要来说:webpack 需要这个入口文件来开始 js 代码的打包。
在以前的版本里 webpack 的入口文件需要在配置文件 webpack.config.js
里指定。
但是现在不需要了,它会默认选择 ./src/index.js 这个文件。
测试这个新特性很容易,创建一个 ./src/index.js
:
console.log(`I'm a silly entry point`)
重新试试构建:
npm run build
你会在 ~/webpack-4-quickstart/dist/main.js
得到你打包后的文件。
咦?等一下。都不需要指定输出文件吗?是的。
在 webpack 4 中是不需要指定入口和输出文件。
webpack 的真正本领是代码拆分。但是相信我,有一个零配置的工具可以让你更加高效。
所以这就是第一个新特性:他会把 ./src/index.js
默认为入口文件,把打包后的文件放在 ./dist/main.js
。
下一章后我们能看到另一个有用的特性:生产和开发模式。
Webpack 4: 生产和开发模式
在项目中整两份配置文件是很正常的事了。
一个典型的例子:
- 一个开发用的配置文件,用来定义 webpack 的 dev server 和其他东西
- 一个生产环境用的配置文件,用来定义
UglifyJSPlugin
,sourcemap 和其他东西。
但是在 webpack4 中你能够不写一行配置。
咋这么流弊呢?
webpack 4 介绍了生产( production
) 和开发( development
) 两种模式。
实际上如果你关注过 npm run build 的输出信息你会看到这个警告:
The ‘mode’ option has not been set. Set ‘mode’ option to ‘development’ or ‘production’ to enable defaults for this environment.
这是什么意思?我们看看。
打开 package.json 文件添加如下脚本
"scripts": {
"dev": "webpack --mode development",
"build": "webpack --mode production"
}
现在运行:
npm run dev
查看 ./dist/main.js
文件。你看到了什么?嘿嘿,嗯,他没有被压缩!
现在这样:
npm run build
现在再看,你看到什么?是不是压缩了!
是的!
生产模式开启了一系列额外的优化。包括 minification
, scope hoisting
, tree-shaking
等, 点赞 ?。
另外开发模式为了优化速度,就没有做压缩了。
所以这是第二个新特性:生产和开发模式。
在 webpack4 你不需要一行配置,只需要一个 --mode
选项。
webpack 4:覆盖默认的入口/出口文件
我喜欢 webpack4 的零配置,但是,如果我要覆盖默认的入口或者出口配置要怎么做呢?
在 package.json
里配置他们。
比如:
"scripts": {
"dev": "webpack --mode development ./foo/src/js/index.js --output ./foo/main.js",
"build": "webpack --mode production ./foo/src/js/index.js --output ./foo/main.js"
}
webpack 4:用 Babel 7 转译 ES6 的 js 代码
现在大家都习惯用 ES6 写 Javascript。
但是不是所有浏览器都知道怎么处理 ES6。我们需要做一些转换。
这个转换的步骤叫做 transpiling
。transpiling 是指把 ES6 转译成浏览器能够识别的代码。
webpack 本身并不知道如何去转换,但是有 loaders
。把他们想象成转换器。
babel-loader
是 webpack 的一个 loader,可以把 ES6 以上的代码转译成 ES5。
为了使用这个 loader 我们需要去安装一系列的依赖。特别是:
- babel-core
- babel-loader
- babel-preset-env (for compiling Javascript ES6 code down to ES5)
先安了吧:
npm i babel-core babel-loader babel-preset-env --save-dev
下一步我们在项目目录下建立一个 .babelrc
文件用来配置 Babel。
{
"presets": ["env"]
}
在这里我们有两个途径去配置 babel-loader:
- 用 webpack 的配置文件
- 在 npm 脚本里使用
--module-bind
擦,说好的零配置呢,这怎么又跟我谈配置,童话里都是骗人的。
So,为什么我们又要写配置文件了呢。
原来 webpack 4 的零配置指的是:
- 入口文件。默认是
./src/index.js
- 出口文件。默认是
./dist/main.js
- 生产和开发模式(无需创建两套配置文件)
就这些了。对于 loaders 我们仍然需要使用配置文件哦,微笑 ?。
作者就这件事问过 Sean(webpack 的核心开发者)。在 webpack 4 中 loaders 是否和 webpack 3 中没有区别?有计划对这些通用的 loaders 比如 babel-loader 提供零配置吗?
他的回答是:
在未来的版本(v4 之后,可能是 4.x 或者 5.0),我们已经开始探索预设或附加系统如何帮助我们定义这一点。我们不想要的是:把一堆东西塞到核心代码里去。我们需要的是:能够支持扩展。
对于现在来说你仍必须依赖 webpack.config.js。
webpack 4:通过配置文件使用 babel-loader
创建一个名叫 webpack.config.js 的文件然后配置 loader:
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
}
]
}
}
没有必要去指定入口文件除非你想指定。
下一步打开 ./src/index.js 然后写一些 ES6 代码:
const arr = [1, 2, 3]
const iAmJavascriptES6 = () => console.log(...arr)
window.iAmJavascriptES6 = iAmJavascriptES6
最后打包:
npm run build
然后去 ./dist/main.js
看看转换后的代码。
webpack 4:不通过配置文件使用 babel-loader
还有一种使用 webpack loaders 的方法。
--module-bind
选项让你从命令行指定 loaders。
这个选项并不是 webpack 4 独有的。3 开始就有了。
你可以这样在 package.json
中使用:
"scripts": {
"dev": "webpack --mode development --module-bind js=babel-loader",
"build": "webpack --mode production --module-bind js=babel-loader"
}
然后你就可以开始构建了。
我并不是很喜欢这种方法(不喜欢太长的 npm 脚本),尽管如此它很有趣。
webpack 4:在 webpack 4 中配置 React
如果你已经安装配置好了 babel 这会很简单。
安装 React:
npm i react react-dom --save-dev
添加 babel-preset-react:
npm i babel-preset-react --save-dev
在 .babelrc
里配置 preset
{
"presets": ["env", "react"]
}
这样就可以了。
如 Conner Aiken 建议的你可以配置 babel-loader 也去加载 .jsx
文件。这在你使用 jsx 扩展名的时候很有用。
打开 webpack.config.js 然后这样配置:
module.exports = {
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
}
]
}
}
测试是否搭好你可以在 ./src/App.js 里创建一个 React 组件。
import React from 'react'
import ReactDOM from 'react-dom'
const App = () => {
return (
<div>
<p>React here!</p>
</div>
)
}
export default App
ReactDOM.render(<App />, document.getElementById('app'))
然后在 ./src/index.js 中引入:
import App from './App'
重新构建试试
webpack 4:HTML 插件
webpack 需要两个额外的组件去处理 HTML:html-webpack-plugin
和 html-loader
。
添加这两个依赖:
npm i html-webpack-plugin html-loader --save-dev
然后更新 webpack 的配置
const HtmlWebPackPlugin = require('html-webpack-plugin')
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
},
{
test: /\.html$/,
use: [
{
loader: 'html-loader',
options: { minimize: true }
}
]
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: './src/index.html',
filename: './index.html'
})
]
}
在 ./src/index.html 新建一个 HTML 文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>webpack 4 quickstart</title>
</head>
<body>
<div id="app">
</div>
</body>
</html>
运行:
npm run build
查看 ./dist
目录。你会看到运行后的结果。
没有必要在你的 HTML 文件中引入你的 JavaScript:它会自动地注入进去。
在浏览器打开 ./dist/index.html
:你可以看到 React 组件运行起来了!
如你所见在处理 HTML 上并没有什么新变化。
webpack 4 目前仍然是一个针对 js 的模块的打包工具。
但是有这个想法,就是添加 HTML 作为一个模块(比如把 HTML 作为入口文件)。
webpack 4: 提取 CSS 到文件中
webpack 并不知道怎么去提取 CSS 到文件中。
在之前这都是交给 extract-text-webpack-plugin
完成的。
不幸的是这个插件在 webpack 4 已经实在玩不动了。
Michael Ciniawsky 说:
维护 extract-text-webpack-plugin 是一个很大的负担,而且这不是第一次因为这货不给力,使得升级 webpack 的主版本都变得异常艰难。
这货被拍死在沙滩后,mini-css-extract-plugin
是来替代它的。
提示:你得把 webpack 版本升级到 4.2.0,才能用这个插件!
安装它:
npm i mini-css-extract-plugin css-loader --save-dev
然后建立一个 CSS 文件用来测试:
/* */
/* CREATE THIS FILE IN ./src/main.css */
/* */
body {
line-height: 2;
}
配置 loader 和 plugin:
const HtmlWebPackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
},
{
test: /\.html$/,
use: [
{
loader: 'html-loader',
options: { minimize: true }
}
]
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: './src/index.html',
filename: './index.html'
}),
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[id].css'
})
]
}
最后在入口文件中引入 CSS:
// PATH OF THIS FILE: ./src/index.js
import style from './main.css'
构建:
npm run build
查看 ./dist
目录,你应该能看到 CSS 的结果!
重点回顾:extract-text-webpack-plugin
在 webpack 4 中不能用了。请使用 mini-css-extract-plugin
。
webpack 4:webpack dev server
在你改变代码后运行 npm run dev?这不是个理想的做法。花几分钟去配置下 webpack 的开发服务。一旦配置了 webpack dev server 它会在浏览器中加载你的 app。
只要你改变了文件,它会自动地刷新浏览器的页面。
安装下面的包来搭建 webpack dev server
:
npm i webpack-dev-server --save-dev
然后打开 package.json
调整脚本:
"scripts": {
"start": "webpack-dev-server --mode development --open",
"build": "webpack --mode production"
}
保存关闭。
现在运行:
npm run start
你就会看到 webpack dev server 在浏览器中加载你的应用了。
webpack dev server
非常适合用来开发。(而且它能使得的 React Dev Tools 在浏览器中正常的工作)