常用的 loader
Webpack 可以处理任何非 js 语言,得益于社区提供的丰富的 loader,日常开发中所使用到的 loader,都可以在社区找到。这里对一些常用的 loader 进行简要的说明。
- babel-loader 将 ES2015+ 代码转译为 ES5。
- ts-loader 将 TypeScript 代码转译为 ES5。
- css-loader 解析
@import
和url()
,并对引用的依赖进行解析。
- style-loader 在 HTML 中注入
<style>
标签将 css 添加到 DOM 中。通常与css-loader
结合使用。
- sass-loader 加载 sass/scss 文件并编译成 css。
- postcss-loader 使用 PostCSS 加载和转译 CSS 文件。
- html-loader 将 HTML 导出为字符串。
- vue-loader 加载和转译 Vue 组件。
- url-loader 和
file-loader
一样,但如果文件小于配置的限制值,可以返回data URL
。
- file-loader 将文件提取到输出目录,并返回相对路径。
plugin
插件的使用
插件是 Webpack 的非常重要的功能,Webpack 本身也是建立在插件系统之上的。插件机制极大增强了 Webpack 的功能,为 Webpack 增加了足够的灵活性。通过插件,我们可以在 Webpack 的构建过程中,引入自己的操作,干预构建结果。
我们通过一个示例来看一下插件的使用:
// Webpack .config.js const HtmlWebpack Plugin = require('html-Webpack -plugin'); const Webpack = require('Webpack '); const config = { plugins: [ new Webpack .optimize.UglifyJsPlugin(), new HtmlWebpack Plugin({template: './src/index.html'}) ] }; module.exports = config;
示例中,我们用到了两个插件,一个是内置的 UglifyJsPlugin
插件,该插件对 js 进行压缩,减小文件的体积。一个是外部插件 HtmlWebpack Plugin
,用来自动生成入口文件,并将最新的资源注入到 HTML 中。
常用的插件
- HtmlWebpack Plugin 自动生成入口文件,并将最新的资源注入到 HTML 中。
- CommonsChunkPlugin 用以创建独立文件,常用来提取多个模块中的公共模块。
- DefinePlugin 用以定义在编译时使用的全局常量。
- DllPlugin 拆分 bundle 减少不必要的构建。
- ExtractTextWebpack Plugin 将文本从 bundle 中提取到单独的文件中。常见的场景是从 bundle 中将 css 提取到独立的 css 文件中。
- HotModuleReplacementPlugin 在运行过程中替换、添加或删除模块,而无需重新加载整个页面。
- UglifyjsWebpack Plugin 对 js 进行压缩,减小文件的体积。
- CopyWebpack Plugin 将单个文件或整个目录复制到构建目录。一个常用的场景是将项目中的静态图片不经构建直接复制到构建后的目录。
4 如何使用 Webpack
下面我们通过一个简单的例子来看一下 Webpack 的使用。这里假定你已经安装了最新版本的 nodejs 和 npm,因为使用旧版本可能会遇到各种问题。
4.1 安装
创建 Webpack -demo 目录,初始化 npm,并且在 Webpack -demo 目录中安装 Webpack 和 Webpack -cli:
mkdir Webpack -demo && cd Webpack -demo npm init -y npm install Webpack Webpack -cli --save-dev
Webpack -cli 用来在命令行中运行 Webpack 。这里建议本地安装 Webpack 和 Webpack -cli,因为全局安装的话,Webpack 的升级会影响到所有的项目。
接下来我们先在项目中新增一些目录和文件:
Webpack -demo ├── package.json ├── dist ├── index.html └── src └── index.js
index.html 内容如下:
<!doctype html> <html> <head> <title>Webpack -demo</title> </head> <body> <script src="./src/index.js"></script> </body> </html>
src/index.js 内容如下:
function createEl() { var element = document.createElement('div') element.innerHTML = 'hello world' return element; } document.body.appendChild(createEl());
4.2 第一次构建
在命令行运行:
./node_modules/.bin/Webpack Hash: 2353b0d3d427eaa8a18a Version: Webpack 4.29.6 Time: 175ms Built at: 2019-04-03 22:08:36 Asset Size Chunks Chunk Names main.js 1 KiB 0 [emitted] main Entrypoint main = main.js [0] ./src/index.js 175 bytes {0} [built]
大家可以发现,我们并没有在配置文件中指定打包的入口和输出的出口,也没有在命令行中指定配置参数,但可以看到在 ./dist 目录下新增了一个 main.js。这是因为 Webpack 配置中 entry 的默认值为 ./src,出口的默认目录是 ./dist。
Webpack -demo ├── package.json ├── dist | └── main.js ├── index.html └── src └── index.js
构建后的项目目录中新增了 main.js。
<!doctype html> <html> <head> <title>Webpack -demo</title> </head> <body> <script src="./dist/main.js"></script> </body> </html>
我们现在将 index.html 中的脚本引用修改为构建后的文件 ./dist/main.js,在浏览器预览,如果一切正常应该可以看到页面上会输出文本 hello world
。
4.3 使用配置文件
对于简单的构建,Webpack 基本可以做到零配置。但对于复杂的单页应用而言,则需要使用 Webpack 的配置文件来提供个性化的功能。
首先我们在项目根目录下新增 Webpack .config.js
文件:
// Webpack .config.js const path = require('path'); module.exports = { entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') } };
在配置文件中,通过 entry
指定了入口文件为 ./src/index.js
,通过 output 指定了输出的目录为 ./dist
,输出的文件名为 bundle.js
。目录结构更新如下:
Webpack -demo ├── package.json ├── Webpack .config.js ├── index.html ├── dist | └── bundle.js └── src └── index.js
同时为了调用简单,我们在 package.json 文件中设置快捷命令来调用 ./node_modules/.bin/Webpack
。
// package.json { "scripts": { "build": "Webpack " } }
再次执行构建命令:
npm run build > Webpack -demo@1.0.0 build C:\work\tech\Webpack -demo > Webpack Hash: d0fa6b1e011af414e622 Version: Webpack 4.29.6 Time: 157ms Built at: 2019-04-03 22:42:50 Asset Size Chunks Chunk Names bundle.js 1 KiB 0 [emitted] main Entrypoint main = bundle.js [0] ./src/index.js 175 bytes {0} [built]
将 index.html
中的 script 引用链接修改为 ./dist/bundle.js
,在浏览器中预览页面,不出意外的话会输出文本 hello world
。