@wy
2018-06-21T16:56:42.000000Z
字数 4375
阅读 515
webpack
Webpack 是一个打包模块化 JavaScript 的工具,在 Webpack 里一切文件皆模块,通过 Loader 转换文件,通过 Plugin 注入钩子,最后输出由多个模块组合成的文件。Webpack 专注于构建模块化项目。
一切文件:JavaScript、CSS、SCSS、图片、模板,在 Webpack 眼中都是一个个模块,这样的好处是能清晰的描述出各个模块之间的依赖关系,以方便 Webpack 对模块进行组合和打包。 经过 Webpack 的处理,最终会输出浏览器能使用的静态资源。
Webpack的优点是:
Webpack的优点是,配置也相当的繁琐。
Webpack 有以下几个核心概念:
Entry:入口,Webpack 执行构建的第一步将从 Entry 开始,可抽象成输入。
Output:输出结果,在 Webpack 经过一系列处理并得出最终想要的代码后输出结果。
Loader:模块转换器,用于把模块原内容按照需求转换成新内容。
Plugin:扩展插件,在 Webpack 构建流程中的特定时机注入扩展逻辑来改变构建结果或做你想要的事情。
Module:模块,在 Webpack 里一切皆模块,一个模块对应着一个文件。Webpack 会从配置的 Entry 开始递归找出所有依赖的模块。
Chunk:代码块,一个 Chunk 由多个模块组合而成,用于代码合并与分割。
bundle: 打包后打包输出的文件。
Webpack 启动后会从 Entry 里配置的 Module 开始递归解析 Entry 依赖的所有 Module。 每找到一个 Module, 就会根据配置的 Loader 去找出对应的转换规则,对 Module 进行转换后,再解析出当前 Module 依赖的 Module。 这些模块会以 Entry 为单位进行分组,一个 Entry 和其所有依赖的 Module 被分到一个组也就是一个 Chunk。最后 Webpack 会把所有 Chunk 转换成文件输出为bundle。 在整个流程中 Webpack 会在恰当的时机执行 Plugin 里定义的逻辑。
npm i -g webpack
可在全局命令中使用webpack命令
npm i webpack -save-dev
npm i -D webpack@
这种安装的方式,不能在全局使用webpack命令,只能在本项目中使用,安装的命令在node_modules/.bin/webpack中,想要webpack命令生效,可以通过以下简便途径
"scripts": {
"start": "webpack --config webpack.config.js"
}
scripts中设置每个属性对应一段 Shell 脚本,其底层实现原理是通过调用 Shell 去运行脚本命令,例如执行 npm run start 命令等同于执行命令 webpack --config webpack.config.js。
这样在命令行中使用npm提供的命令来执行:
npm run start
即便webpack不是全局的命令,也可以在node_modules/.bin文件中找到对应的命令。
通过 Webpack 构建一个采用 CommonJS 或者 ES6 模块化编写的项目,该项目有个网页会通过 JavaScript 在网页中显示两数相加的结果。
写一个JS 工具函数文件 tools.js,采用 ES6 模块化方式, 包含两个函数 add和isFunction,代码如下:
export function add(a,b) {
return a + b;
}
export let isFunction = (f) => {
return typeof f === 'function';
}
再写一个工具函数 utils.js,采用 CommonJS 规范:
module.exports = {
css(el, attr,value){ // 给一个元素设置某个样式
el.style[attr] = value;
}
}
写一个入口的 app.js 用来引入 tools.js 和 utils.js文件:
import {add} from './tools.js'
const utils = require('./utils.js');
let str = '<p>做加法运算:1 + 2=' + add(1,2)+'</p>';
let app = document.getElementById('app');
// 给app元素添加背景
utils.css(app,'background','red')
app.innerHTML = str;
此时app.js就是webpack打包的入口,可以以下命令打包:
webpack [entryFile] [outputFile]
webpack app.js build.js
使用命令后会在目录下生成一个build.js文件,在本地创建index.html引入build.js:
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<div id="app"></div>
<!--导入 Webpack 输出的 JavaScript 文件-->
<script src="./build.js"></script>
</body>
</html>
build.js 文件是一个可执行的 JavaScript 文件,它包含页面所依赖的两个模块 utils.js 和 tools.js 及内置的webpack启动函数。
Webpack 是一个打包模块化 JavaScript 的工具,它会从 app.js 出发,识别出源码中的模块化导入语句, 递归的寻找出入口文件的所有依赖,把入口和其所有依赖打包到一个单独的文件中。 从 Webpack2 开始,已经内置了对 ES6、CommonJS、AMD 模块化语句的支持。
除了使用命令行打包外,可以在目录下创建webpack的配置文件,可以更灵活的扩展需要的配置项。webpack默认的配置文件为 webpack.config.js,也可以通过命令参数指定不同的配置文件:
webpack --config webpack.other.conf.js
先来使用默认的配置文件webpack.config.js,在文件中使用 CommonJS规范导出一个对象:
module.exports = {
entry:'./app.js',
output:{
filename:'build.js',
path: __dirname+"/dist"
}
}
entry为入口文件配置,规定从哪个文件开始找依赖
可以是以下三种中的一种或者相互组合:
类型 | 例子 | 含义 |
---|---|---|
String | './app/entry' | 入口模块的文件路径,可以是相对路径。 |
Array | ['./app/entry1', './app/entry2'] | 入口模块的文件路径,可以是相对路径。 |
Object | { a: './app/entry-a', b: ['./app/entry-b1', './app/entry-b2']} | 配置多个入口,每个入口生成一个 Chunk |
Chunk 名称:
Webpack 会为每个生成的 Chunk 取一个名称,Chunk 的名称和 Entry 的配置有关:
output 配置如何输出最终想要的代码。output 是一个 object,里面包含一系列配置项。
filename
output.filename 配置输出文件的名称,为string 类型。 如果只有一个输出文件,则可以把它写成静态不变的:
filename: 'bundle.js'
但是在有多个 Chunk 要输出时,就需要借助模版和变量了。前面说到 Webpack 会为每个 Chunk取一个名称,可以根据 Chunk 的名称来区分输出的文件名:
filename: '[name].js'
代码里的 [name] 代表用内置的 name 变量去替换[name],这时你可以把它看作一个字符串模块函数, 每个要输出的 Chunk 都会通过这个函数去拼接出输出的文件名称。
内置变量除了 name 还包括:
变量名 | 含义 |
---|---|
id | Chunk 的唯一标识,从0开始 |
name | Chunk 的名称 |
hash | Chunk 的唯一标识的 Hash 值 |
chunkhash | Chunk 内容的 Hash 值 |
其中 hash 和 chunkhash 的长度是可指定的,[hash:8] 代表取8位 Hash 值,默认是20位。
注意 ExtractTextWebpackPlugin 插件是使用 contenthash 来代表哈希值而不是 chunkhash, 原因在于 ExtractTextWebpackPlugin 提取出来的内容是代码内容本身而不是由一组模块组成的 Chunk。
path
output.path 配置输出文件存放在本地的目录,必须是 string 类型的绝对路径。通常通过 Node.js 的 path 模块去获取绝对路径:
path: path.resolve(__dirname, 'dist_[hash]')
publicPath
在复杂的项目里可能会有一些构建出的资源需要异步加载,加载这些异步资源需要对应的 URL 地址。
output.publicPath 配置发布到线上资源的 URL 前缀,为string 类型。 默认值是空字符串 '',即使用相对路径。
这样说可能有点抽象,举个例子,需要把构建出的资源文件上传到 CDN 服务上,以利于加快页面的打开速度。配置代码如下:
filename:'[name]_[chunkhash:8].js'
publicPath: 'https://cdn.example.com/assets/'
这时发布到线上的 HTML 在引入 JavaScript 文件时就需要:
< script src='https://cdn.example.com/assets/a_12345678.js'>