本文介绍了一些 webpack 的核心概念以及一些概念术语,并对核心配置作了一些简单的用法讲解。建议刚刚接触 Webpack 的朋友能够先了解一下。想了解更多 Webpack 使用以及配置的话能够参考个人下一篇文章: 从零开始搭建一个 Webpack 开发环境配置(附 Demo)css
模块化开发的趋势 咱们在开发的过程当中,以前都是使用引入 script 的方式进行各类工具和插件的引入,可是这样会形成很大程度上的全局污染,因此引入了 模块化 的概念,可是不论是 commomJs 仍是 CMD,AMD 的方式,浏览器都没法识别,而使用 webpack 就能够自动的将文件编译成浏览器能够识别的代码node
less、sass 以及 ES6 语法的使用 一样的,直接使用 less、sass 和 ES6 语法,直接使用,浏览器甚至 node 环境也没法正常识别,因此这时候 loader 就派上用场了,可使用 less-loader、sass-loader 以及 babel-lodaer 对对应的文件进行转换以后,就能够正常的编译了webpack
监听文件的变化并自动刷新网页,作到实时预览web
提供 HTTP 服务而不是使用本地文件预览npm
对于打包后的文件进行压缩,模块拆分,减少打包后的文件体积数组
等等还有不少别的优点,这里我就不一一列举了浏览器
全局安装:缓存
npm install --global webpack
复制代码
本地安装:sass
npm install --save-dev webpack
npm install --save-dev webpack-cli
复制代码
webpack 是一个可高度配置的现代 JavaScript 应用程序模块打包器。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图,其中包含应用程序须要的每一个模块,而后将全部这些模块打包成一个或多个 bundle。bash
入口点能够告诉 webpack 从哪里启动以及遵循依赖关系图,以此知道要打包什么东西。你能够考虑将待打包文件的根目录做为你应用程序的入口点。
我的理解:入口就是 webpack 在处理应用程序时,须要知道从哪一个文件开始执行,这个文件就是整个程序的入口文件。
用法:entry: string|Array|Object
webpack.config.js
const config = {
entry: './src/index.js'
};
module.exports = config;
复制代码
通常适用于多页面应用,多个入口的场景。
webpack.config.js
const config = {
entry: ['./src/entry1', './src/entry2']
};
module.exports = config;
复制代码
通常适用于分离 应用程序(app) 和 第三方库(vendor) 入口。
webpack.config.js
const config = {
entry: {
app: './src/app.js',
vendors: './src/vendors.js'
}
};
module.exports = config;
复制代码
假如项目里有多个页面须要为每一个页面的入口配置一个 Entry ,但这些页面的数量可能会不断增加,则这时 Entry 的配置会受到到其余因素的影响致使不能写成静态的值。
webpack.config.js
// 同步函数
entry: () => {
return {
a:'./pages/a',
b:'./pages/b',
}
};
// 异步函数
entry: () => {
return new Promise((resolve)=>{
resolve({
a:'./pages/a',
b:'./pages/b',
});
});
};
复制代码
上面既然已经有入口文件了,那么 webpack 执行了一系列操做以后,生成的新的打包后的文件应该放到哪儿呢,因此咱们须要指定一下。
在 webpack 中配置 output 属性的最低要求是,将它的值设置为一个对象,包括如下两点:
webpack.config.js
const path = require('path');
const config = {
entry: './src/index.js',
output: {
// 最基本的两个配置要求
filename: 'bundle.js', // 输出文件的文件名
path: path.resolve(__dirname, 'dist') // 目标输出目录 path 的绝对路径,这里必须是绝对路径
}
};
module.exports = config;
复制代码
若是配置建立了多个单独的 "chunk",则应该使用占位符(参考*内置的占位符变量*)来确保每一个文件具备惟一的名称。
webpack.config.js
const path = require('path');
const config = {
output: {
// 最基本的两个配置要求
filename: '[name]-bundle.js', // 输出文件的文件名
path: path.resolve(__dirname, 'dist') // 目标输出目录 path 的绝对路径
}
};
module.exports = config;
复制代码
变量名 | 含义 |
---|---|
id | Chunk 的惟一标识,从0开始 |
name | Chunk 的名称 |
hash | Chunk 的惟一标识的 Hash 值 |
chunkhash | Chunk 内容的 Hash 值 |
loader 用于对模块的源代码进行转换。loader 可使你在 import
、require()
或"加载"模块时预处理文件。 loader 能够将文件从不一样的语言(如 TypeScript)转换为 JavaScript,或将内联图像转换为 data URL。loader 甚至容许你直接在 JavaScript 模块中 import CSS文件!
例如:加载 css 模块:
安装对应的 loader
npm install --save-dev style-loader css-loader
复制代码
而后指示 webpack 对每一个 .css 使用 css-loader 和 style-loader
webpack.config.js
``` js
module.exports = {
module: {
rules: [
{ test: /\.css$/, use: ['style-loader', 'css-loader' }
]
}
};
```
复制代码
rules 配置模块的读取和解析规则,一般用来配置 Loader。其类型是一个数组,数组里每一项都描述了如何去处理部分文件。 配置一项 rules 时大体经过如下方式:
条件匹配:经过 test 、 include 、 exclude 三个配置项来命中 Loader 要应用规则的文件
应用规则:对选中后的文件经过 use 配置项来应用 Loader,能够只应用一个 Loader 或者按照从后往前的顺序应用一组 Loader,同时还能够分别给 Loader 传入参数
重置顺序:一组 Loader 的执行顺序默认是从右到左(从下到上、从后到前)执行,经过 enforce 选项可让其中一个 Loader 的执行顺序放到最前或者最后
在 Loader 须要传入不少参数时,你还能够经过一个 Object 来描述
test include exclude 这三个命中文件的配置项能够传入一个字符串或正则,其实它们还都支持数组类型
具体使用:
module.exports = {
module: {
rules: [
{
// 命中 JavaScript 文件
test: [
/\.js?$/,
/\.jsx?$/
],
// 用 babel-loader 转换 JavaScript 文件
// ?cacheDirectory 表示传给 babel-loader 的参数,用于缓存 babel 编译结果加快从新编译速度
use: [
{
loader:'babel-loader',
options:{
cacheDirectory:true,
},
// enforce:'post' 的含义是把该 Loader 的执行顺序放到最后
// enforce 的值还能够是 pre,表明把 Loader 的执行顺序放到最前面
enforce:'post'
}
],
// 只命中src目录里的js文件,加快 Webpack 搜索速度
include: path.resolve(__dirname, 'src')
},
{
// 命中 SCSS 文件
test: /\.scss$/,
// 使用一组 Loader 去处理 SCSS 文件。
// 处理顺序为从后到前,即先交给 sass-loader 处理,再把结果交给 css-loader 最后再给 style-loader。
use: ['style-loader', 'css-loader', 'sass-loader'],
// 排除 node_modules 目录下的文件
exclude: path.resolve(__dirname, 'node_modules')
}
]
}
};
复制代码
Plugin 是用来扩展 Webpack 功能的,经过在构建流程里注入钩子实现,它给 Webpack 带来了很大的灵活性。
好比每次打包文件到 dist 文件夹下,就可能致使文件夹下面的文件过多,内容过大,那么此时咱们可能须要在打包以前先将 dist 文件下的文件都删除掉,可是每次都手动删除岂不是太麻烦,此时咱们就可使用 clean-webpack-plugin 插件来帮助咱们清理 dist 文件夹
插件安装
npm install clean-webpack-plugin --save-dev
复制代码
webpack.config.js
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
plugins: [
new CleanWebpackPlugin(['dist'])
]
}
复制代码
这是一个广泛的术语,用于图片、字体、媒体,还有一些其余类型的文件,经常使用在网站和其余应用程序。这些文件一般最终在输出(output ) 中成为单个文件,但也能够经过一些东西内联,像 style-loader 或者 url-loader 。
由多个不一样的模块生成,bundles 包含了早已通过加载和编译的最终源文件版本。
这是 webpack 特定的术语被用在内部来管理 building 过程。bundle 由 chunk 组成,其中有几种类型(例如,入口 chunk(entry chunk) 和子 chunk(child chunk))。一般 chunk 会直接对应所输出的 bundle,可是有一些配置并不会产生一对一的关系。
有时候一个文件依赖于其余文件,webpack 将其视为依赖关系(dependency)。从一个或多个入口点开始,webpack 递归构建一个依赖关系图,里面包含了你的应用程序须要的全部模块/资源(mudule/asset)。
提供比完整程序接触面(surface area)更小的离散功能块。精心编写的模块提供了可靠的抽象和封装界限,使得应用程序中每一个模块都具备条理清楚的设计和明确的目的。
移除未使用/多余的代码,或者更准确地说,只导入引用的代码。编译器(compiler)(例如 webpack)将经过分析各类 import 语句和引入代码的使用状况,来肯定哪些部分的依赖关系被实际使用,删除不是“树”的部分,以实现此功能
从 app.js 和 vendors.js 开始建立依赖图(dependency graph)。这些依赖图是彼此彻底分离、互相独立的,容许你使用 CommonsChunkPlugin 从「应用程序 bundle」中提取 vendor 引用(vendor reference) 到 vendor bundle。能够帮助你在 webpack 中实现被称为长效缓存的通用模式。
Bundle 分离(Bundle Splitting) 这个流程提供一个优化 build 的方法,容许 webpack 为应用程序生成多个 bundle。最终效果是,当其余某些 bundle 的改动时,彼此独立的另外一些 bundle 均可以不受到影响,减小须要从新发布的代码量,所以由客户端从新下载并利用浏览器缓存。
代码分离(Code Splitting) 指将代码分离到每一个 bundles/chunks 里面,你能够按需加载,而不是加载一个包含所有的 bundle。
本文简单介绍了一下 Webpack 的做用以及 Webpack 核心概念的用法。想了解更多的朋友能够参考个人下一篇文章:从零开始搭建一个 Webpack 开发环境配置(附 Demo)