webpack安装及使用
Posted html资讯期刊
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了webpack安装及使用相关的知识,希望对你有一定的参考价值。
起步
查看原文|编辑此页
webpack 用于编译 javascript 模块。一旦完成安装,你就可以通过 webpack 的 CLI 或 API 与其配合交互。如果你还不熟悉 webpack,请阅读核心概念和打包器对比,了解为什么你要使用 webpack,而不是社区中的其他工具。
基本安装
首先我们创建一个目录,初始化 npm,然后 在本地安装 webpack,接着安装 webpack-cli(此工具用于在命令行中运行 webpack):
mkdir webpack-demo && cd webpack-demo
npm init -y
npm install webpack webpack-cli --save-dev
贯穿整个指南的是,我们将使用
diff
块,来显示我们对目录、文件和代码所做的更改。
现在我们将创建以下目录结构、文件和内容:
project
webpack-demo
|- package.json+ |- index.html+ |- /src+ |- index.js
src/index.js
function component() {
var element = document.createElement('div');
// Lodash(目前通过一个 script 脚本引入)对于执行这一行是必需的
element.innerHTML = _.join(['Hello', 'webpack'], ' ');
return element;}document.body.appendChild(component());
index.html
<!doctype html><html>
<head>
<title>起步</title>
<script src="https://unpkg.com/lodash@4.16.6"></script>
</head>
<body>
<script src="./src/index.js"></script>
</body></html>
我们还需要调整 package.json
文件,以便确保我们安装包是私有的(private)
,并且移除 main
入口。这可以防止意外发布你的代码。
如果你想要了解
package.json
内在机制的更多信息,我们推荐阅读 npm 文档。
package.json
{
"name": "webpack-demo",
"version": "1.0.0",
"description": "",+ "private": true,- "main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^4.0.1",
"webpack-cli": "^2.0.9"
},
"dependencies": {}
}
在此示例中,<script>
标签之间存在隐式依赖关系。index.js
文件执行之前,还依赖于页面中引入的 lodash
。之所以说是隐式的是因为 index.js
并未显式声明需要引入 lodash
,只是假定推测已经存在一个全局变量 _
。
使用这种方式去管理 JavaScript 项目会有一些问题:
无法立即体现,脚本的执行依赖于外部扩展库(external library)。
如果依赖不存在,或者引入顺序错误,应用程序将无法正常运行。
如果依赖被引入但是并没有使用,浏览器将被迫下载无用代码。
让我们使用 webpack 来管理这些脚本。
创建一个 bundle 文件
首先,我们稍微调整下目录结构,将“源”代码(/src
)从我们的“分发”代码(/dist
)中分离出来。“源”代码是用于书写和编辑的代码。“分发”代码是构建过程产生的代码最小化和优化后的“输出”目录,最终将在浏览器中加载:
project
webpack-demo
|- package.json+ |- /dist+ |- index.html- |- index.html
|- /src
|- index.js
要在 index.js
中打包 lodash
依赖,我们需要在本地安装 library:
npm install --save lodash
在安装一个要打包到生产环境的安装包时,你应该使用
npm install --save
,如果你在安装一个用于开发环境的安装包(例如,linter, 测试库等),你应该使用npm install --save-dev
。请在 npm 文档 中查找更多信息。
现在,在我们的脚本中 import lodash
:
src/index.js
+ import _ from 'lodash';+
function component() {
var element = document.createElement('div');- // Lodash, currently included via a script, is required for this line to work+ // Lodash, now imported by this script
element.innerHTML = _.join(['Hello', 'webpack'], ' ');
return element;
}
document.body.appendChild(component());
现在,由于通过打包来合成脚本,我们必须更新 index.html
文件。因为现在是通过 import
引入 lodash,所以将 lodash <script>
删除,然后修改另一个 <script>
标签来加载 bundle,而不是原始的 /src
文件:
dist/index.html
<!doctype html>
<html>
<head>
<title>起步</title>- <script ></script>
</head>
<body>- <script ></script>+ <script ></script>
</body>
</html>
在这个设置中,index.js
显式要求引入的 lodash
必须存在,然后将它绑定为 _
(没有全局作用域污染)。通过声明模块所需的依赖,webpack 能够利用这些信息去构建依赖图,然后使用图生成一个优化过的,会以正确顺序执行的 bundle。
可以这样说,执行 npx webpack
,会将我们的脚本作为入口起点,然后 输出 为 main.js
。Node 8.2+ 版本提供的 npx
命令,可以运行在初始安装的 webpack 包(package)的 webpack 二进制文件(./node_modules/.bin/webpack
):
npx webpack
Hash: dabab1bac2b940c1462b
Version: webpack 4.0.1
Time: 3003ms
Built at: 2018-2-26 22:42:11
Asset Size Chunks Chunk Names
main.js 69.6 KiB 0 [emitted] main
Entrypoint main = main.js [1] (webpack)/buildin/module.js 519 bytes {0} [built]
[2] (webpack)/buildin/global.js 509 bytes {0} [built]
[3] ./src/index.js 256 bytes {0} [built]
+ 1 hidden module
WARNING in configuration(配置警告)The 'mode' option has not been set. Set 'mode' option to 'development' or 'production' to enable defaults for this environment.('mode' 选项还未设置。将 'mode' 选项设置为 'development' 或 'production',来启用环境默认值。)
输出可能会稍有不同,但是只要构建成功,那么你就可以继续。并且不要担心,稍后我们就会解决。
在浏览器中打开 index.html
,如果一切访问都正常,你应该能看到以下文本:'Hello webpack'。
模块
ES2015 中的 import
和 export
语句已经被标准化。虽然大多数浏览器还无法支持它们,但是 webpack 却能够提供开箱即用般的支持。
事实上,webpack 在幕后会将代码“转译”,以便旧版本浏览器可以执行。如果你检查 dist/bundle.js
,你可以看到 webpack 具体如何实现,这是独创精巧的设计!除了 import
和 export
,webpack 还能够很好地支持多种其他模块语法,更多信息请查看模块 API。
注意,webpack 不会更改代码中除 import
和 export
语句以外的部分。如果你在使用其它 ES2015 特性,请确保你在 webpack 的 loader 系统中使用了一个像是 Babel 或 Bublé 的转译器。
使用一个配置文件
在 webpack 4 中,可以无须任何配置使用,然而大多数项目会需要很复杂的设置,这就是为什么 webpack 仍然要支持 配置文件。这比在终端(terminal)中手动输入大量命令要高效的多,所以让我们创建一个取代以上使用 CLI 选项方式的配置文件:
project
webpack-demo
|- package.json+ |- webpack.config.js
|- /dist
|- index.html
|- /src
|- index.js
webpack.config.js
const path = require('path');module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
}};
现在,让我们通过新配置文件再次执行构建:
npx webpack --config webpack.config.js
Hash: dabab1bac2b940c1462b
Version: webpack 4.0.1
Time: 328ms
Built at: 2018-2-26 22:47:43
Asset Size Chunks Chunk Names
bundle.js 69.6 KiB 0 [emitted] main
Entrypoint main = bundle.js [1] (webpack)/buildin/module.js 519 bytes {0} [built]
[2] (webpack)/buildin/global.js 509 bytes {0} [built]
[3] ./src/index.js 256 bytes {0} [built]
+ 1 hidden module
WARNING in configuration(配置警告)The 'mode' option has not been set. Set 'mode' option to 'development' or 'production' to enable defaults for this environment.('mode' 选项还未设置。将 'mode' 选项设置为 'development' 或 'production',来启用环境默认值。)
注意,当在 windows 中通过调用路径去调用
webpack
时,必须使用反斜线()。例如node_modules\.bin\webpack --config webpack.config.js
。
如果
webpack.config.js
存在,则webpack
命令将默认选择使用它。我们在这里使用--config
选项只是向你表明,可以传递任何名称的配置文件。这对于需要拆分成多个文件的复杂配置是非常有用。
比起 CLI 这种简单直接的使用方式,配置文件具有更多的灵活性。我们可以通过配置方式指定 loader 规则(loader rules)、插件(plugins)、解析选项(resolve options),以及许多其他增强功能。了解更多详细信息,请查看配置文档。
NPM 脚本(NPM Scripts)
考虑到用 CLI 这种方式来运行本地的 webpack 不是特别方便,我们可以设置一个快捷方式。在 package.json 添加一个 npm 脚本(npm script):
package.json
{
"name": "webpack-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",+ "build": "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^4.0.1",
"webpack-cli": "^2.0.9",
"lodash": "^4.17.5"
}
}
现在,可以使用 npm run build
命令,来替代我们之前使用的 npx
命令。注意,使用 npm 的 scripts
,我们可以像使用 npx
那样通过模块名引用本地安装的 npm 包。这是大多数基于 npm 的项目遵循的标准,因为它允许所有贡献者使用同一组通用脚本(如果必要,每个 flag 都带有 --config
标志)。
现在运行以下命令,然后看看你的脚本别名是否正常运行:
npm run build
Hash: dabab1bac2b940c1462b
Version: webpack 4.0.1
Time: 323ms
Built at: 2018-2-26 22:50:25
Asset Size Chunks Chunk Names
bundle.js 69.6 KiB 0 [emitted] main
Entrypoint main = bundle.js [1] (webpack)/buildin/module.js 519 bytes {0} [built]
[2] (webpack)/buildin/global.js 509 bytes {0} [built]
[3] ./src/index.js 256 bytes {0} [built]
+ 1 hidden module
WARNING in configuration(配置警告)The 'mode' option has not been set. Set 'mode' option to 'development' or 'production' to enable defaults for this environment.('mode' 选项还未设置。将 'mode' 选项设置为 'development' 或 'production',来启用环境默认值。)
通过向
npm run build
命令和你的参数之间添加两个中横线,可以将自定义参数传递给 webpack,例如:npm run build -- --colors
。
结论
现在,你已经实现了一个基本的构建过程,你应该移至下一章节的 Asset Management
指南,以了解如何通过 webpack 来管理资源,例如图片、字体。此刻你的项目应该和如下类似:
project
webpack-demo
|- package.json
|- webpack.config.js
|- /dist
|- bundle.js
|- index.html
|- /src
|- index.js
|- /node_modules
如果你使用的是 npm 5,你可能还会在目录中看到一个
package-lock.json
文件。管理资源
查看原文|编辑此页
如果你是从开始一直遵循着指南的示例,现在会有一个小项目,显示 "Hello webpack"。现在我们尝试整合一些其他资源,比如图像,看看 webpack 如何处理。
在 webpack 出现之前,前端开发人员会使用 grunt 和 gulp 等工具来处理资源,并将它们从
/src
文件夹移动到/dist
或/build
目录中。同样方式也被用于 JavaScript 模块,但是,像 webpack 这样的工具,将动态打包(dynamically bundle)所有依赖项(创建所谓的依赖图(dependency graph))。这是极好的创举,因为现在每个模块都可以明确表述它自身的依赖,我们将避免打包未使用的模块。webpack 最出色的功能之一就是,除了 JavaScript,还可以通过 loader 引入任何其他类型的文件。也就是说,以上列出的那些 JavaScript 的优点(例如显式依赖),同样可以用来构建网站或 web 应用程序中的所有非 JavaScript 内容。让我们从 CSS 开始起步,或许你可能已经熟悉了这个设置过程。
安装
在开始之前,让我们对项目做一个小的修改:
dist/index.html
<!doctype html> <html> <head>- <title>Getting Started</title>+ <title>Asset Management</title> </head> <body> <script ></script> </body> </html>
加载 CSS
为了从 JavaScript 模块中
import
一个 CSS 文件,你需要在module
配置中 安装并添加 style-loader 和 css-loader:npm install --save-dev style-loader css-loader
webpack.config.js
const path = require('path'); module.exports = { entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') },+ module: {+ rules: [+ {+ test: /\.css$/,+ use: [+ 'style-loader',+ 'css-loader'+ ]+ }+ ]+ } };
webpack 根据正则表达式,来确定应该查找哪些文件,并将其提供给指定的 loader。在这种情况下,以
.css
结尾的全部文件,都将被提供给style-loader
和css-loader
。这使你可以在依赖于此样式的文件中
import './style.css'
。现在,当该模块运行时,含有 CSS 字符串的<style>
标签,将被插入到 html 文件的<head>
中。我们尝试一下,通过在项目中添加一个新的
style.css
文件,并将其导入到我们的index.js
中:project
webpack-demo |- package.json |- webpack.config.js |- /dist |- bundle.js |- index.html |- /src+ |- style.css |- index.js |- /node_modules
src/style.css
.hello { color: red;}
src/index.js
import _ from 'lodash';+ import './style.css'; function component() { var element = document.createElement('div'); // lodash 是由当前 script 脚本 import 导入进来的 element.innerHTML = _.join(['Hello', 'webpack'], ' ');+ element.classList.add('hello'); return element; } document.body.appendChild(component());
现在运行构建命令:
npm run build Hash: 9a3abfc96300ef87880f Version: webpack 2.6.1 Time: 834ms Asset Size Chunks Chunk Names bundle.js 560 kB 0 [emitted] [big] main [0] ./~/lodash/lodash.js 540 kB {0} [built] [1] ./src/style.css 1 kB {0} [built] [2] ./~/css-loader!./src/style.css 191 bytes {0} [built] [3] ./~/css-loader/lib/css-base.js 2.26 kB {0} [built] [4] ./~/style-loader/lib/addStyles.js 8.7 kB {0} [built] [5] ./~/style-loader/lib/urls.js 3.01 kB {0} [built] [6] (webpack)/buildin/global.js 509 bytes {0} [built] [7] (webpack)/buildin/module.js 517 bytes {0} [built] [8] ./src/index.js 351 bytes {0} [built]
再次在浏览器中打开
index.html
,你应该看到Hello webpack
现在的样式是红色。要查看 webpack 做了什么,请检查页面(不要查看页面源代码,因为它不会显示结果),并查看页面的 head 标签。它应该包含我们在index.js
中导入的 style 块元素。请注意,在多数情况下,你也可以进行 CSS 分离,以便在生产环境中节省加载时间。最重要的是,现有的 loader 可以支持任何你可以想到的 CSS 处理器风格 - postcss, sass 和 less 等。
加载图片
假想,现在我们正在下载 CSS,但是我们的背景和图标这些图片,要如何处理呢?使用 file-loader,我们可以轻松地将这些内容混合到 CSS 中:
npm install --save-dev file-loader
webpack.config.js
const path = require('path'); module.exports = { entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') }, module: { rules: [ { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },+ {+ test: /\.(png|svg|jpg|gif)$/,+ use: [+ 'file-loader'+ ]+ } ] } };
现在,当你
import MyImage from './my-image.png'
,该图像将被处理并添加到output
目录,_并且_MyImage
变量将包含该图像在处理后的最终 url。当使用 css-loader 时,如上所示,你的 CSS 中的url('./my-image.png')
会使用类似的过程去处理。loader 会识别这是一个本地文件,并将'./my-image.png'
路径,替换为输出
目录中图像的最终路径。html-loader 以相同的方式处理<img />
。我们向项目添加一个图像,然后看它是如何工作的,你可以使用任何你喜欢的图像:
project
webpack-demo |- package.json |- webpack.config.js |- /dist |- bundle.js |- index.html |- /src+ |- icon.png |- style.css |- index.js |- /node_modules
src/index.js
import _ from 'lodash'; import './style.css';+ import Icon from './icon.png'; function component() { var element = document.createElement('div'); // Lodash,现在由此脚本导入 element.innerHTML = _.join(['Hello', 'webpack'], ' '); element.classList.add('hello');+ // 将图像添加到我们现有的 div。+ var myIcon = new Image();+ myIcon.src = Icon;++ element.appendChild(myIcon); return element; } document.body.appendChild(component());
src/style.css
.hello { color: red;+ background: url('./icon.png'); }
让我们重新构建,并再次打开 index.html 文件:
npm run build Hash: 854865050ea3c1c7f237 Version: webpack 2.6.1 Time: 895ms Asset Size Chunks Chunk Names 5c999da72346a995e7e2718865d019c8.png 11.3 kB [emitted] bundle.js 561 kB 0 [emitted] [big] main [0] ./src/icon.png 82 bytes {0} [built] [1] ./~/lodash/lodash.js 540 kB {0} [built] [2] ./src/style.css 1 kB {0} [built] [3] ./~/css-loader!./src/style.css 242 bytes {0} [built] [4] ./~/css-loader/lib/css-base.js 2.26 kB {0} [built] [5] ./~/style-loader/lib/addStyles.js 8.7 kB {0} [built] [6] ./~/style-loader/lib/urls.js 3.01 kB {0} [built] [7] (webpack)/buildin/global.js 509 bytes {0} [built] [8] (webpack)/buildin/module.js 517 bytes {0} [built] [9] ./src/index.js 503 bytes {0} [built]
如果一切顺利,和
Hello webpack
文本旁边的img
元素一样,现在看到的图标是重复的背景图片。如果你检查此元素,你将看到实际的文件名已更改为像5c999da72346a995e7e2718865d019c8.png
一样。这意味着 webpack 在src
文件夹中找到我们的文件,并成功处理过它!合乎逻辑下一步是,压缩和优化你的图像。查看 image-webpack-loader 和 url-loader,以了解更多关于如果增强加载处理图片功能。
加载字体
那么,像字体这样的其他资源如何处理呢?file-loader 和 url-loader 可以接收并加载任何文件,然后将其输出到构建目录。这就是说,我们可以将它们用于任何类型的文件,包括字体。让我们更新
webpack.config.js
来处理字体文件:webpack.config.js
const path = require('path'); module.exports = { entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') }, module: { rules: [ { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] }, { test: /\.(png|svg|jpg|gif)$/, use: [ 'file-loader' ] },+ {+ test: /\.(woff|woff2|eot|ttf|otf)$/,+ use: [+ 'file-loader'+ ]+ } ] } };
在项目中添加一些字体文件:
project
webpack-demo |- package.json |- webpack.config.js |- /dist |- bundle.js |- index.html |- /src+ |- my-font.woff+ |- my-font.woff2 |- icon.png |- style.css |- index.js |- /node_modules
通过配置好 loader 并将字体文件放在合适的地方,你可以通过一个
@font-face
声明引入。本地的url(...)
指令会被 webpack 获取处理,就像它处理图片资源一样:src/style.css
+ @font-face {+ font-family: 'MyFont';+ src: url('./my-font.woff2') format('woff2'),+ url('./my-font.woff') format('woff');+ font-weight: 600;+ font-style: normal;+ } .hello { color: red;+ font-family: 'MyFont'; background: url('./icon.png'); }
现在让我们重新构建来看看 webpack 是否处理了我们的字体:
npm run build Hash: b4aef94169088c79ed1c Version: webpack 2.6.1 Time: 775ms Asset Size Chunks Chunk Names 5c999da72346a995e7e2718865d019c8.png 11.3 kB [emitted]11aebbbd407bcc3ab1e914ca0238d24d.woff 221 kB [emitted] bundle.js 561 kB 0 [emitted] [big] main [0] ./src/icon.png 82 bytes {0} [built] [1] ./~/lodash/lodash.js 540 kB {0} [built] [2] ./src/style.css 1 kB {0} [built] [3] ./~/css-loader!./src/style.css 420 bytes {0} [built] [4] ./~/css-loader/lib/css-base.js 2.26 kB {0} [built] [5] ./src/MyFont.woff 83 bytes {0} [built] [6] ./~/style-loader/lib/addStyles.js 8.7 kB {0} [built] [7] ./~/style-loader/lib/urls.js 3.01 kB {0} [built] [8] (webpack)/buildin/global.js 509 bytes {0} [built] [9] (webpack)/buildin/module.js 517 bytes {0} [built] [10] ./src/index.js 503 bytes {0} [built]
重新打开
index.html
看看我们的Hello webpack
文本显示是否换上了新的字体。如果一切顺利,你应该能看到变化。加载数据
此外,可以加载的有用资源还有数据,如 JSON 文件,CSV、TSV 和 XML。类似于 NodeJS,JSON 支持实际上是内置的,也就是说
import Data from './data.json'
默认将正常运行。要导入 CSV、TSV 和 XML,你可以使用 csv-loader 和 xml-loader。让我们处理这三类文件:npm install --save-dev csv-loader xml-loader
webpack.config.js
const path = require('path'); module.exports = { entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') }, module: { rules: [ { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] }, { test: /\.(png|svg|jpg|gif)$/, use: [ 'file-loader' ] }, { test: /\.(woff|woff2|eot|ttf|otf)$/, use: [ 'file-loader' ] },+ {+ test: /\.(csv|tsv)$/,+ use: [+ 'csv-loader'+ ]+ },+ {+ test: /\.xml$/,+ use: [+ 'xml-loader'+ ]+ } ] } };
给你的项目添加一些数据文件:
project
webpack-demo |- package.json |- webpack.config.js |- /dist |- bundle.js |- index.html |- /src+ |- data.xml |- my-font.woff |- my-font.woff2 |- icon.png |- style.css |- index.js |- /node_modules
src/data.xml
<?xml version="1.0" encoding="UTF-8"?><note> <to>Mary</to> <from>John</from> <heading>Reminder</heading> <body>Call Cindy on Tuesday</body></note>
现在,你可以
import
这四种类型的数据(JSON, CSV, TSV, XML)中的任何一种,所导入的Data
变量将包含可直接使用的已解析 JSON:src/index.js
import _ from 'lodash'; import './style.css'; import Icon from './icon.png';+ import Data from './data.xml'; function component() { var element = document.createElement('div'); // Lodash, now imported by this script element.innerHTML = _.join(['Hello', 'webpack'], ' '); element.classList.add('hello'); // Add the image to our existing div. var myIcon = new Image(); myIcon.src = Icon; element.appendChild(myIcon);+ console.log(Data); return element; } document.body.appendChild(component());
当你打开
index.html
并查看开发者工具中的控制台,你应该能够看到你导入的数据被打印在了上面!在使用 d3 等工具来实现某些数据可视化时,预加载数据会非常有用。我们可以不用再发送 ajax 请求,然后于运行时解析数据,而是在构建过程中将其提前载入并打包到模块中,以便浏览器加载模块后,可以立即从模块中解析数据。
全局资源
上述所有内容中最出色之处是,以这种方式加载资源,你可以以更直观的方式将模块和资源组合在一起。无需依赖于含有全部资源的
/assets
目录,而是将资源与代码组合在一起。例如,类似这样的结构会非常有用:- |- /assets+ |– /components+ | |– /my-component+ | | |– index.jsx+ | | |– index.css+ | | |– icon.svg+ | | |– img.png
这种配置方式会使你的代码更具备可移植性,因为现有的统一放置的方式会造成所有资源紧密耦合在一起。假如你想在另一个项目中使用
/my-component
,只需将其复制或移动到/components
目录下。只要你已经安装了任何扩展依赖(external dependencies),并且你已经在配置中定义过相同的 loader,那么项目应该能够良好运行。但是,假如你无法使用新的开发方式,只能被固定于旧有开发方式,或者你有一些在多个组件(视图、模板、模块等)之间共享的资源。你仍然可以将这些资源存储在公共目录(base directory)中,甚至配合使用 alias 来使它们更方便
import 导入
。回退处理
对于接下来的指南,我们无需使用本指南中所有用到的资源,因此我们会进行一些清理工作,以便为下一部分指南中的管理输出章节做好准备:
project
webpack-demo |- package.json |- webpack.config.js |- /dist |- bundle.js |- index.html |- /src- |- data.xml- |- my-font.woff- |- my-font.woff2- |- icon.png- |- style.css |- index.js |- /node_modules
webpack.config.js
const path = require('path'); module.exports = { entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') },- module: {- rules: [- {- test: /\.css$/,- use: [- 'style-loader',- 'css-loader'- ]- },- {- test: /\.(png|svg|jpg|gif)$/,- use: [- 'file-loader'- ]- },- {- test: /\.(woff|woff2|eot|ttf|otf)$/,- use: [- 'file-loader'- ]- },- {- test: /\.(csv|tsv)$/,- use: [- 'csv-loader'- ]- },- {- test: /\.xml$/,- use: [- 'xml-loader'- ]- }- ]- } };
src/index.js
import _ from 'lodash';- import './style.css';- import Icon from './icon.png';- import Data from './data.xml';- function component() { var element = document.createElement('div'); -- // Lodash,现在通过 script 标签导入 element.innerHTML = _.join(['Hello', 'webpack'], ' ');- element.classList.add('hello');-- // 将图像添加到我们已有的 div 中。- var myIcon = new Image();- myIcon.src = Icon;-- element.appendChild(myIcon);-- console.log(Data); return element; } document.body.appendChild(component());
管理输出
查看原文|编辑此页
本指南继续沿用
管理资源
指南中的代码示例。到目前为止,我们在
index.html
文件中手动引入所有资源,然而随着应用程序增长,并且一旦开始对文件名使用哈希(hash)]并输出多个 bundle,手动地对index.html
文件进行管理,一切就会变得困难起来。然而,可以通过一些插件,会使这个过程更容易操控。预先准备
首先,让我们调整一下我们的项目:
project
webpack-demo |- package.json |- webpack.config.js |- /dist |- /src |- index.js+ |- print.js |- /node_modules
我们在
src/print.js
文件中添加一些逻辑:src/print.js
export default function printMe() { console.log('I get called from print.js!');}
并且在
src/index.js
文件中使用这个函数:src/index.js
import _ from 'lodash';+ import printMe from './print.js'; function component() { var element = document.createElement('div');+ var btn = document.createElement('button'); element.innerHTML = _.join(['Hello', 'webpack'], ' ');+ btn.innerHTML = 'Click me and check the console!';+ btn.onclick = printMe;++ element.appendChild(btn); return element; } document.body.appendChild(component());
我们还要更新
dist/index.html
文件,来为 webpack 分离入口做好准备:dist/index.html
<!doctype html> <html> <head>- <title>Asset Management</title>+ <title>Output Management</title>+ <script ></script> </head> <body>- <script ></script>+ <script ></script> </body> </html>
现在调整配置。我们将在 entry 添加
src/print.js
作为新的入口起点(webpack.config.js
const path = require('path'); module.exports = {- entry: './src/index.js',+ entry: {+ app: './src/index.js',+ print: './src/print.js'+ }, output: {- filename: 'bundle.js',+ filename: '[name].bundle.js', path: path.resolve(__dirname, 'dist') } };
执行
npm run build
,然后看到生成如下:Hash: aa305b0f3373c63c9051 Version: webpack 3.0.0 Time: 536ms Asset Size Chunks Chunk Names app.bundle.js 545 kB 0, 1 [emitted] [big] app print.bundle.js 2.74 kB 1 [emitted] print [0] ./src/print.js 84 bytes {0} {1} [built] [1] ./src/index.js 403 bytes {0} [built] [3] (webpack)/buildin/global.js 509 bytes {0} [built] [4] (webpack)/buildin/module.js 517 bytes {0} [built] + 1 hidden module
我们可以看到,webpack 生成
print.bundle.js
和app.bundle.js
文件,这也和我们在index.html
文件中指定的文件名称相对应。如果你在浏览器中打开index.html
,就可以看到在点击按钮时会发生什么。但是,如果我们更改了我们的一个入口起点的名称,甚至添加了一个新的名称,会发生什么?生成的包将被重命名在一个构建中,但是我们的
index.html
文件仍然会引用旧的名字。我们用HtmlWebpackPlugin
来解决这个问题。设定 HtmlWebpackPlugin
首先安装插件,并且调整
webpack.config.js
文件:npm install --save-dev html-webpack-plugin
webpack.config.js
const path = require('path');+ const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: { app: './src/index.js', print: './src/print.js' },+ plugins: [+ new HtmlWebpackPlugin({+ title: 'Output Management'+ })+ ], output: { filename: '[name].bundle.js', path: path.resolve(__dirname, 'dist') } };
在我们构建之前,你应该了解,虽然在
dist/
文件夹我们已经有index.html
这个文件,然而HtmlWebpackPlugin
还是会默认生成index.html
文件。这就是说,它会用新生成的index.html
文件,把我们的原来的替换。让我们看下在执行npm run build
后会发生什么:Hash: 81f82697c19b5f49aebd Version: webpack 2.6.1 Time: 854ms Asset Size Chunks Chunk Names print.bundle.js 544 kB 0 [emitted] [big] print app.bundle.js 2.81 kB 1 [emitted] app index.html 249 bytes [emitted] [0] ./~/lodash/lodash.js 540 kB {0} [built] [1] (webpack)/buildin/global.js 509 bytes {0} [built] [2] (webpack)/buildin/module.js 517 bytes {0} [built] [3] ./src/index.js 172 bytes {1} [built] [4] multi lodash 28 bytes {0} [built]Child html-webpack-plugin for "index.html": [0] ./~/lodash/lodash.js 540 kB {0} [built] [1] ./~/html-webpack-plugin/lib/loader.js!./~/html-webpack-plugin/default_index.ejs 538 bytes {0} [built] [2] (webpack)/buildin/global.js 509 bytes {0} [built] [3] (webpack)/buildin/module.js 517 bytes {0} [built]
如果你在代码编辑器中将
index.html
打开,你就会看到HtmlWebpackPlugin
创建了一个全新的文件,所有的 bundle 会自动添加到 html 中。如果你想要了解更多
HtmlWebpackPlugin
插件提供的全部功能和选项,那么你就应该多多熟悉HtmlWebpackPlugin
仓库。你还可以看一下
html-webpack-template
,除了默认模板之外,还提供了一些额外的功能。清理
/dist
文件夹你可能已经注意到,由于过去的指南和代码示例遗留下来,导致我们的
/dist
文件夹相当杂乱。webpack 会生成文件,然后将这些文件放置在/dist
文件夹中,但是 webpack 无法追踪到哪些文件是实际在项目中用到的。通常,在每次构建前清理
/dist
文件夹,是比较推荐的做法,因此只会生成用到的文件。让我们完成这个需求。
clean-webpack-plugin
是一个比较普及的管理插件,让我们安装和配置下。npm install clean-webpack-plugin --save-dev
webpack.config.js
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin');+ const CleanWebpackPlugin = require('clean-webpack-plugin'); module.exports = { entry: { app: './src/index.js', print: './src/print.js' }, plugins: [+ new CleanWebpackPlugin(['dist']), new HtmlWebpackPlugin({ title: 'Output Management' }) ], output: { filename: '[name].bundle.js', path: path.resolve(__dirname, 'dist') } };
现在执行
npm run build
,再检查/dist
文件夹。如果一切顺利,你现在应该不会再看到旧的文件,只有构建后生成的文件!-------今天就到这里,明天继续!想要学习的可以自己亲自试下代码!有问题也可以留言交流!
以上是关于webpack安装及使用的主要内容,如果未能解决你的问题,请参考以下文章
VUE学习笔记:14.模块化开发之webpack简介,安装及基本使用