WebPack 是一个现代 JavaScript 应用程序的模块打包器(module bundler),它将目作为一个整体,通过入口文件(如index.js)找到所有的依赖文件,并递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后使用loaders将所有这些模块打包成少量的(通常只有一个)、浏览器可以识别的bundle,再交给由浏览器去加载。其目的就是解决现在前端越来越复杂的文件依赖问题。
从 webpack 4.0.0 版本开始,可以不用通过引入一个配置文件打包项目。然而,webpack 仍然还是 高度可配置的,并且能够很好的满足需求。
一、优势:
- 模块化:它能把各种资源,如JS、coffee、样式(含less/scss)、图片等都作为模块来使用和处理,把复杂的程序简单化
- 方便旧代码迁移:它的脚本使用CommonJS形式来书写,并提供对AMD/CMD的支持,因此很方便的就可以把旧代码迁移
- 可扩展性强:WebPack有一个智能解析器,能处理几乎所有的第三方库,支持多种插件
二、四个核心概念
- 入口(entry):是WebPack打包各个文件依赖关系的起点(entry point),它告诉 WebPack 从哪里开始,并根据依赖关系图确定需要打包的内容。
入口起点(entry point)指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始,webpack 会找出有哪些模块和 library 是入口起点(直接和间接)依赖的。
默认值是
./src/index.js
,然而,可以通过在 webpack 配置中配置 entry 属性,来指定一个不同的入口起点(或者也可以指定多个入口起点)。
1 module.exports = { 2 entry: './path/to/my/entry/file.js' 3 };
- 输出(output):是告诉WebPack如何去处理这些打包文件,并且最终这些打包内容生成到哪里。
主输出文件默认为 ./dist/main.js
,其他生成文件的默认输出目录是 ./dist
。
你可以通过在配置(webpack.config.js)中指定一个 output
字段,来配置这些处理过程:
1 const path = require('path'); 2 3 module.exports = { 4 entry: './path/to/my/entry/file.js', 5 output: { 6 path: path.resolve(__dirname, 'dist'), 7 filename: 'my-first-webpack.bundle.js' 8 } 9 };
- Loader:是WebPack中相对比较重要的一个概念,它需要识别出(identify)应该被对应的 loader 进行转换(transform)的那些文件并且转换这些文件,从而使其能够被添加到依赖图中。
作为开箱即用的自带特性,webpack 自身只支持 JavaScript。而 loader 能够让 webpack 处理那些非 JavaScript 文件,并且先将它们转换为有效 模块,然后添加到依赖图中,这样就可以提供给应用程序使用。
注意,loader 能够
import
导入任何类型的模块(例如.css
文件),这是 webpack 特有的功能,其他打包程序或任务执行器的可能并不支持。我们认为这种语言扩展是有很必要的,因为这可以使开发人员创建出更准确的依赖关系图。
1 const path = require('path'); 2 3 module.exports = { 4 output: { 5 filename: 'my-first-webpack.bundle.js' 6 }, 7 module: { 8 rules: [ 9 { test: /\.txt$/, use: 'raw-loader' } 10 ] 11 } 12 };
在更高层面,在 webpack 的配置中 loader 有两个特征:
-
test
属性,用于标识出应该被对应的 loader 进行转换的某个或某些文件。use
属性,表示进行转换时,应该使用哪个 loader。
- 插件(plugins):相对于Loader而言的不同之处在于Loader 仅在每个文件的基础上执行转换,而插件(plugins) 更常用于在打包模块的 “compilation” 和 “chunk” 生命周期执行操作和自定义功能。
loader 被用于转换某些类型的模块,而插件则可以用于执行范围更广的任务,插件的范围包括:打包优化、资源管理和注入环境变量。
想要使用一个插件,你只需要 require()
它,然后把它添加到 plugins
数组中。多数插件可以通过选项(option)自定义。你也可以在一个配置文件中因为不同目的而多次使用同一个插件,这时需要通过使用 new
操作符来创建它的一个实例。
1 const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装 2 const webpack = require('webpack'); // 用于访问内置插件 3 4 module.exports = { 5 module: { 6 rules: [ 7 { test: /\.txt$/, use: 'raw-loader' } 8 ] 9 }, 10 plugins: [ 11 new HtmlWebpackPlugin({template: './src/index.html'}) 12 ] 13 };
三、浏览器兼容性:
webpack 支持所有 ES5 兼容(IE8 及以下不提供支持)的浏览器。webpack 的 import()
和 require.ensure()
需要环境中有 Promise
。如果你想要支持旧版本浏览器,你应该在使用这些 webpack 提供的表达式之前,先 加载一个 polyfill。