共计 5191 个字符,预计需要花费 13 分钟才能阅读完成。
Webpack是一个模块打包器。其主要目的是将 JavaScript
文件捆绑在浏览器中使用,但它也能够转换,捆绑或打包任何资源或资产,使用依赖关系的模块并生成代表这些模块的静态形式 (.js, .css, .png),Webpack 是运行在 Node.js 环境中,它是模块化解决方案的一种。
什么是模块化
比如一个网站它有三个页面 A、B、C。页面对应的 js: A => {a.js, b.js}, B => {a.js, c.js, d.js}, C => {a.js, e.js, c.js}。
他们都有引入了a.js
,可以独立生成a.vendor.js
。然而 B,C 都引入a.js
, c.js
,可以独立成ac.vednor.js
。
为什么使用 Webpack
最大的好处就是配置完一键打包生成相应模块,通过插件还可以处理压缩,版本号,sourceMap,通过 loader 自动编译转换.less、.sass、.vue、.react 等文件。无论对单入口还是多入口支持就非常到位,像其它的类似工具 (browserify
) 对多入口没有 Webpack 强大。
Install
在使用 Webpack 之前需要安装 Node.js, 下载地址
NPM
使用 npm
进行安装,安装 node.js
会自动安装npm
[root@BF-meshell webpack]# npm install --save-dev webpack
YARN
通过 yarn
安装
[root@BF-meshell webpack]# npm install yarn -g // 先安装 yarn
[root@BF-meshell webpack]
# yarn add webpack –dev
webpack.config.js
webpack.config.js
是 Webpack
配置文件 ( 官方文档 ), 在配置之前我先生成package.json
文件
//npm init 初始化项目的 package.json 文件
[root@BF-meshell webpack]
# npm init
package.json
{
"name": "webpack-example",
"version": "1.0.0",
"description": "","main":"index.js","scripts": {"test":"echo \"Error: no test specified\" && exit 1"},"author":"meShell","license":"MIT","dependencies": { },
"devDependencies": {}}
我们需要修改就是 devDependencies
、dependencies
属性 (项目的依赖库). 通过npmjs 找到你需要的包名.
// 格式以包名为键,版本号为值。"devDependencies": {
"jquery": "^3.2.1",
"superagent": "^3.8.1"
}
在配置完 devDependencies
和dependencies
就可以执行安装依赖.
[root@BF-meshell webpack]# npm install
模块文件(入口文件)
新建两个入口文件 index.js
,content.js
两个文件都包含各自需要的类库以及应用代码,分别代表首页和内容的 js 文件. 主要功能就是显示当前页面的名称,取得远程的 JSON 数据显示出来。他们公用了两个类库jQuery 4 和superagent。有了入口文件就开始配置webpack.config.js
。
const path = require("path");
const webpack = require("webpack");
const htmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry: {
index: "./index",
content: "./content",
},
output: {path: path.resolve(__dirname, \'dist\'),
filename: "[name].js"
}
};
这是 webpack
的基本配置。在目录执行 webpack
命令就会生成目录 dist
同时在目录下生成 index.js
和content.js
。
[root@BF-meshell webpack]# webpack
Hash: 052f1069368009e4662d
Version: webpack 3.8.1
Time: 2099ms
Asset Size Chunks Chunk Names
content.js 314 kB 0 [emitted] content
index.js 314 kB 0 [emitted] index
entry 和 output
entry
和 output
是配置文件里必须填写的属性.entry项目入口点可以是字符串,数组,对象形式来表达.
比如是单页面应用只有入口文件就可以这样的配置 entry:"./app"
; output 作为入口点的输出形式如文件目录,文件名。
上面的配置是没有分离库和应用代码,而是将所有库都打包进 index.js
和content.js
,我们使用 webpack
自带的 CommonsChunkPlugin 插件来分离公共库和应用代码.
CommonsChunkPlugin
该插件功能是从多个入口文件中分离出公共库文件为一个独立的块文件。以 index.js
和content.js
为例,两个都加载了 jquery
和superagent
库只需配置如下代码到配置文件 (plugins 属性) 中就会分离出一个 common.js
文件出来。
new webpack.optimize.CommonsChunkPlugin({names: ["common"],
})
这样就会把 jquery
和superagent
库合并到 common.js
中给页面加载如:
也可以通过 chunks
来指定入口文件分离.
new webpack.optimize.CommonsChunkPlugin({names: ["common"],
chunks: ["index", "content"]
})
可以查看 https://github.com/webpack/webpack/tree/master/examples/multiple-commons-chunks 这个事例。上面我们完成了代码分离,我们需要两个 html 页面分测试最终效果这里用到HtmlWebpackPlugin.
new htmlWebpackPlugin({filename: "index.html",}),
new htmlWebpackPlugin({filename: "content.html",}),
将插件代码加入到配置中.
const path = require("path");
const webpack = require("webpack");
const htmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry: {
index: "./index",
content: "./content",
},
output: {path: path.resolve(__dirname, \'dist\'),
filename: "[name].js"
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({names: ["common", "manifest"],
}),
new htmlWebpackPlugin({filename: "index.html",}),
new htmlWebpackPlugin({filename: "content.html",})
]
};
执行 webpack
命令,生成以下目录文件。
将 index.html
中的 content.js
引入删除和 content.html
的index.js
删除,并在浏览器中查看两个页面的效果。
可以配置 HtmlWebpackPlugin 的 chunks
属性来解决引入多余的 js 文件.
new htmlWebpackPlugin({
filename: "index.html",
// 页面将只会引入 common.js、index.js
chunks: ["common","index"],
})
Loader
前面讲完了代码的分离,现在学习 loader 的使用,webpack
默认只会处理 .js
文件,如果需要将 less
,vue
,sass
等文件处理成可使用状态就要使用 loader
。webpack
将所有的静态资源文件都当成模块,然后通过 loader
来转换,它需要额外安装的,常用的 loader
列表.
Name | Loader |
---|---|
css | css-loader |
less | less-loader |
sass | sass-loader |
style | style-loader |
url | url-loader |
file | file-loader |
json | json-loader |
babel | babel-loader |
html | html-loader |
vue | vue-loader |
[root@BF-meshell webpack]# npm install css-loader less-loader sass-loader style-loader url-loader file-loader babel-loader --save-dev
安装完成之后,在 webpack
配置中添加 rules
规则.
// webpack.config.js
module.exports = {
module: {
rules: [{
test: /\.less$/, // 区配文件是以.less 结尾就 style-loader, css-loader, less-loader 来转换
use: [{loader: "style-loader"}, {loader: "css-loader"}, {
loader: "less-loader", options: {
strictMath: true,
noIeCompat: true
}
}]
}]
}
};
@baseColor: #f938ab;
@whiteColor: #FFFFFF;
body {background-color: saturate(@baseColor, 5%);}
h1 {
color: @whiteColor;
border-width: 1px;
border-style: solid;
border-color: @whiteColor;
}
修改index.js
require("./body.less");
Note:
直接使用webpack
命令并不会直接产生 body.css 文件,我们将要使用extract-text-webpack-plugin
插件将编译的 css 内容提取到文件中.
extract-text-webpack-plugin
修改配置文件,将 extract-text-webpack-plugin
添加进去。
...
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const extractLess = new ExtractTextPlugin({filename: "[name].css",
disable: process.env.NODE_ENV === "development"
});
module.exports = {
...
module: {
rules: [
{
test: /\.less$/, // 区配文件是以.less 结尾就 style-loader, css-loader, less-loader 来转换
use:extractLess.extract({
use: [{loader: "css-loader"}, {loader: "less-loader"}],
// use style-loader in development
fallback: "style-loader"
})
}
]
},
resolve: { },
plugins: [
...
extractLess
]
};
重新编译就会生成一个 index.css
文件,也会直接引入到 index.html
中。
通过上面的几个事例了解 webpack
基础使用,代码分离,loader 使用. 还可以使用插件对生成后的文件进行压缩、sourceMap 文件、版本号、这些官网就有详细的讲解,本教程中就不再讲解.
事例代码https://github.com/TianLiangZhou/loocode-example/tree/master/webpack
推荐阅读