Webpack入门
# 序言
之前一直对webpack都是拿来即用,从来没去了解一些基本概念,Getting Started也没看过。
所以今天看了一下文档,了解了一下基本概念,就简单做个记录。
该文章仅介绍一些基础概念和入门案例,更多请查看官方文档:英文原版 (opens new window)、中文版 (opens new window)
# 什么是webpack
本质上,webpack 是一个用于现代 JavaScript 应用程序的 静态模块打包工具。当 webpack 处理应用程序时,它会在内部构建一个 依赖图(dependency graph),此依赖图对应映射到项目所需的每个模块,并生成一个或多个 bundle。
# 一些核心概念
主要是以下几个keywords
- Entry
- Output
- Loaders
- Plugins
- Mode
- Browser Compatibility
# Entry
用于指定一个入口js文件作为依赖图的开始。
module.exports = {
entry: './path/to/my/entry/file.js',
};
2
3
# Output
告诉 webpack 在哪里输出它所创建的 bundle,以及如何命名这些文件。
主要输出文件的默认值是 ./dist/main.js
,其他生成文件默认放置在 ./dist
文件夹中。
const path = require('path');
module.exports = {
entry: './path/to/my/entry/file.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'my-first-webpack.bundle.js',
},
};
2
3
4
5
6
7
8
9
# loader
让 webpack 能够去处理其他类型的文件,并将它们转换为有效模块,并将其添加到依赖图。
默认可处理JavaScript 和 JSON 文件。
loader由两个属性组成:
test
属性,识别出哪些文件会被转换。use
属性,定义出在进行转换时,应该使用哪个 loader。
const path = require('path');
module.exports = {
output: {
filename: 'my-first-webpack.bundle.js',
},
module: {
rules: [{ test: /\.txt$/, use: 'raw-loader' }],
},
};
2
3
4
5
6
7
8
9
10
以上配置中,对一个单独的 module 对象定义了 rules
属性,里面包含两个必须属性:test
和 use
。这告诉 webpack 编译器(compiler) 如下信息:
“嘿,webpack 编译器,当你碰到「在
require()
/import
语句中被解析为 '.txt' 的路径」时,在你对它打包之前,先 use(使用)raw-loader
转换一下。”
# Plugin
插件可以用于执行范围更广的任务。包括:打包优化,资源管理,注入环境变量。
想要使用一个插件,你只需要 require()
它,然后把它添加到 plugins
数组中。多数插件可以通过选项(option)自定义。你也可以在一个配置文件中因为不同目的而多次使用同一个插件,这时需要通过使用 new
操作符来创建一个插件实例。
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装
const webpack = require('webpack'); // 用于访问内置插件
module.exports = {
module: {
rules: [{ test: /\.txt$/, use: 'raw-loader' }],
},
plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })],
};
2
3
4
5
6
7
8
9
在上面的示例中,html-webpack-plugin
为应用程序生成一个 HTML 文件,并自动注入所有生成的 bundle。
# Mode
通过选择 development
, production
或 none
之中的一个,来设置 mode
参数,你可以启用 webpack 内置在相应环境下的优化。其默认值为 production
。
module.exports = {
mode: 'production',
};
2
3
# Browser Compatibility
webpack 支持所有符合 ES5 标准 (opens new window) 的浏览器(不支持 IE8 及以下版本)。webpack 的 import()
和 require.ensure()
需要 Promise
。如果你想要支持旧版本浏览器,在使用这些表达式之前,还需要 提前加载 polyfill (opens new window)。
# Getting Started
# 基本安装
执行以下命令
mkdir webpack-demo
cd webpack-demo
npm init -y
npm install webpack webpack-cli --save-dev
2
3
4
创建以下目录结构
project
webpack-demo
|- package.json
+ |- index.html
+ |- /src
+ |- index.js
2
3
4
5
src/index.js
function component() {
const element = document.createElement('div');
// lodash(目前通过一个 script 引入)对于执行这一行是必需的
element.innerHTML = _.join(['Hello', 'webpack'], ' ');
return element;
}
document.body.appendChild(component());
2
3
4
5
6
7
8
9
10
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>起步</title>
<script src="https://unpkg.com/lodash@4.17.20"></script>
</head>
<body>
<script src="./src/index.js"></script>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
Lodash (opens new window) 是一个一致性、模块化、高性能的 JavaScript 实用工具库。
我们还需要调整 package.json
文件,以便确保我们安装包是 private(私有的)
,并且移除 main
入口。这可以防止意外发布你的代码。
package.json
{
"name": "webpack-demo",
"version": "1.0.0",
"description": "",
- "main": "index.js",
+ "private": true,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^5.4.0",
"webpack-cli": "^4.2.0"
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 创建一个 bundle
修改目录结构
webpack-demo
|- package.json
+ |- /dist
+ |- index.html
- |- index.html
|- /src
|- index.js
2
3
4
5
6
7
本地安装lodash
npm install --save lodash
在安装一个 要打包到生产环境 bundle 中的package时,,你应该使用
npm install --save
。如果你在安装一个用于开发环境的 package 时(例如,linter, 测试库等),你应该使用npm install --save-dev
。更多信息请查看 npm 文档 (opens new window)。
现在,在我们的 script 中 import lodash
:
src/index.js
+import _ from 'lodash';
+
function component() {
const element = document.createElement('div');
- // lodash(目前通过一个 script 引入)对于执行这一行是必需的
+ // lodash 在当前 script 中使用 import 引入
element.innerHTML = _.join(['Hello', 'webpack'], ' ');
return element;
}
document.body.appendChild(component());
2
3
4
5
6
7
8
9
10
11
12
13
现在,我们将会打包所有脚本,我们必须更新 index.html
文件。由于现在是通过 import
引入 lodash,所以要将 lodash <script>
删除,然后修改另一个 <script>
标签来加载 bundle,而不是原始的 ./src
文件:
dist/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>起步</title>
- <script src="https://unpkg.com/lodash@4.17.20"></script>
</head>
<body>
- <script src="./src/index.js"></script>
+ <script src="main.js"></script>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
执行 npx webpack
,然后打开dist/index.html
,应该就能看到hello webpack了。说明import的js也被打包进去了。
直接运行html出现main.js语法错误,使用vscode open with live server却发现一切正常
初步怀疑是js等级问题,后来f12查看js,发现出现乱码,查看html编码,果然有问题,不知道为什么是utf-16,而js编码为utf-8,遂修改html编码为utf-8,问题解决
# 模块
ES2015(ES6的第一个版本)的import
和export
已十分常见,但是很多浏览器却不能支持,所以webpack默认会将一些模块的语法转换成浏览器可以兼容的方式。除了export
和import
,webpack还支持更多信息查看模块API (opens new window)
webpack 不会更改代码中除 import
和 export
语句以外的部分。如果你在使用其它 ES2015 特性 (opens new window),请确保你在 webpack loader 系统 (opens new window) 中使用了一个像是 Babel (opens new window) 或 Bublé (opens new window) 的 transpiler(转译器) (opens new window)。
# 使用一个配置文件
在以下目录创建配置文件,webpack.config.js
webpack-demo
|- package.json
+ |- webpack.config.js
|- /dist
|- index.html
|- /src
|- index.js
2
3
4
5
6
7
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
},
};
2
3
4
5
6
7
8
9
执行npx webpack --config webpack.config.js
,成功构建。
--config
只是表明可以指定配置文件,缺省值为webpack.config.js,也就是以上的--config可以被省略
# npm scripts
一般情况,我们会将webpack的脚本配置到npm的script中。
package.json
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
+ "build": "webpack"
},
2
3
4
现在,我们就可以直接执行npm run build
来进行打包了。
可以通过在 npm run build 命令与参数之间添加两个连接符的方式向 webpack 传递自定义参数,例如:npm run build -- --color。
也可以在build script中webpack后加上自定义参数
# 管理资源
为了在 JavaScript 模块中 import 一个 CSS 文件,你需要安装 style-loader 和 css-loader,并在 module 配置 中添加这些 loader:
npm install --save-dev style-loader css-loader
同时配置webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
+ module: {
+ rules: [
+ {
+ test: /\.css$/i,
+ use: ['style-loader', 'css-loader'],
+ },
+ ],
+ },
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
这样,项目依赖的CSS将会被打包。
更多资源类型参考官方文档-管理资源 (opens new window)。
# 最后
至此,webpack的入门可以告一段落了,有些这些基本概念和使用方式,相信已经能够让初学者初步使用webpack了。