部分内容主要摘自吴浩麟著《深入浅出Webpack》,今后不再赘述
安装 Webpack
在用 Webpack 执行构建任务时需要通过 webpack
可执行文件去启动构建任务,所以需要安装 webpack
可执行文件。 在安装 Webpack 前请确保你的系统安装了5.0.0及以上版本的 Node.js。
在开始给项目加入构建前,你需要先新建一个 Web 项目,方式包括:
- 新建一个目录,再进入项目根目录执行
npm init
来初始化最简单的采用了模块化开发的项目; - 用脚手架工具 Yeoman 直接快速地生成一个最符合你的需求的项目。
其实从零开始搭建一个项目是一个挺好玩的过程.于是笔者尝试着如文章所说只用npm自带命令,构建了一个最基本的模块化开发项目
构建的结果如下:
安装 Webpack 到本项目
要安装 Webpack 到本项目,可按照你的需要选择以下任意命令运行:
# npm i -D 是 npm install --save-dev 的简写,是指安装模块并保存到 package.json 的 devDependencies
# 安装最新稳定版
npm i -D webpack
# 安装指定版本
npm i -D webpack@
# 安装最新体验版本
npm i -D webpack@beta
使用 Webpack
下面通过 Webpack 构建一个采用 CommonJS 模块化编写的项目,该项目有个网页会通过 JavaScript 在网页中显示 Hello,Webpack。
运行构建前,先把要完成该功能的最基础的 JavaScript 文件和 HTML 建立好,需要如下文件:
页面入口文件 index.html
JS 工具函数文件 show.js
// 操作 DOM 元素,把 content 显示到网页上
function show(content) {
window.document.getElementById('app').innerText = 'Hello,' + content;
}
// 通过 CommonJS 规范导出 show 函数
module.exports = show;
这里提到了CommonJS.简略介绍一下CommonJS的概念.
node应用由模块组成,采用的commonjs模块规范。每一个文件就是一个模块,拥有自己独立的作用域,变量,以及方法等,对其他的模块都不可见。CommonJS规范规定,每个模块内部,module变量代表当前模块。这个变量是一个对象,它的exports属性(即module.exports)是对外的接口。加载某个模块,其实是加载该模块的module.exports属性。require方法用于加载模块。
关于commonJS一起其他模块化JS规范的概念,以后会专门出一期来介绍.本文不作赘述.
JS 执行入口文件 main.js
// 通过 CommonJS 规范导入 show 函数
const show = require('./show.js');
// 执行 show 函数
show('Webpack');
Webpack 在执行构建时默认会从项目根目录下的 webpack.config.js 文件读取配置,所以你还需要新建它,其内容如下:
const path = require('path');
module.exports = {
// JavaScript 执行入口文件
entry: './main.js',
output: {
// 把所有依赖的模块合并输出到一个 bundle.js 文件
filename: 'bundle.js',
// 输出文件都放到 dist 目录下
path: path.resolve(__dirname, './dist'),
}
};
由于 Webpack 构建运行在 Node.js 环境下,所以该文件最后需要通过 CommonJS 规范导出一个描述如何构建的 Object 对象。
此时项目目录如下:
|-- index.html
|-- main.js
|-- show.js
|-- webpack.config.js
一切文件就绪,在项目根目录下执行 webpack 命令运行 Webpack 构建,你会发现目录下多出一个 dist 目录,里面有个 bundle.js 文件, bundle.js 文件是一个可执行的 JavaScript 文件,它包含页面所依赖的两个模块 main.js 和 show.js 及内置的 webpackBootstrap 启动函数。 这时你用浏览器打开 index.html 网页将会看到 Hello,Webpack。
结果如下
Webpack 是一个打包模块化 JavaScript 的工具,它会从 main.js 出发,识别出源码中的模块化导入语句, 递归的寻找出入口文件的所有依赖,把入口和其所有依赖打包到一个单独的文件中。 从 Webpack2 开始,已经内置了对 ES6、CommonJS、AMD 模块化语句的支持。
使用 Loader
继续优化这个网页的 UI,为项目引入 CSS 代码让文字居中显示,main.css 的内容如下:
#app{
text-align: center;
}
Webpack 把一切文件看作模块,CSS 文件也不例外,要引入 main.css 需要像引入 JavaScript 文件那样,修改入口文件 main.js 如下:
// 通过 CommonJS 规范导入 CSS 模块
require('./main.css');
// 通过 CommonJS 规范导入 show 函数
const show = require('./show.js');
// 执行 show 函数
show('Webpack');
但是这样修改后去执行 Webpack 构建是会报错的,因为 Webpack 不原生支持解析 CSS 文件。要支持非 JavaScript 类型的文件,需要使用 Webpack 的 Loader 机制。Webpack的配置修改使用如下:
const path = require('path');
module.exports = {
// JavaScript 执行入口文件
entry: './main.js',
output: {
// 把所有依赖的模块合并输出到一个 bundle.js 文件
filename: 'bundle.js',
// 输出文件都放到 dist 目录下
path: path.resolve(__dirname, './dist'),
},
module: {
rules: [
{
// 用正则去匹配要用该 loader 转换的 CSS 文件
test: /\.css$/,
use: ['style-loader', 'css-loader?minimize'],
}
]
}
};
Loader 可以看作具有文件转换功能的翻译员,配置里的 module.rules
数组配置了一组规则,告诉 Webpack 在遇到哪些文件时使用哪些 Loader 去加载和转换。 如上配置告诉 Webpack 在遇到以 .css
结尾的文件时先使用 css-loader
读取 CSS 文件,再交给 style-loader
把 CSS 内容注入到 JavaScript 里。 在配置 Loader 时需要注意的是:
-
use
属性的值需要是一个由 Loader 名称组成的数组,Loader 的执行顺序是由后到前的; - 每一个 Loader 都可以通过 URL querystring 的方式传入参数,例如
css-loader?minimize
中的minimize
告诉css-loader
要开启 CSS 压缩。
想知道 Loader 具体支持哪些属性,则需要我们查阅文档,例如 css-loader
还有很多用法,我们可以在 css-loader 主页 上查到。
在重新执行 Webpack 构建前要先安装新引入的 Loader:
npm i -D style-loader css-loader
安装成功后重新执行构建时,你会发现 bundle.js 文件被更新了,里面注入了在 main.css 中写的 CSS,而不是会额外生成一个 CSS 文件。 但是重新刷新 index.html 网页时将会发现 Hello,Webpack 居中了,样式生效了!
也许你会对此感到奇怪,第一次看到 CSS 被写在了 JavaScript 里!这其实都是 style-loader 的功劳,它的工作原理大概是把 CSS 内容用 JavaScript 里的字符串存储起来, 在网页执行 JavaScript 时通过 DOM 操作动态地往 HTML head 标签里插入 HTML style 标签。