- 翻译作者: 饭团爸爸
资源管理
如果你已经读过webpack指南 初探 那么你已经有一个简单的 'Hello webpack' 的项目。现在让我尝试去添加一些其它的资源,比如说图片,看看 webpack 是如何处理的。
在有 webpack 之前,前端开发工程师使用 grunt 或者 gulp 等工具去处理资源文件,然后将它们从src
文件夹移动到/dist
或者/build
文件夹中。类似的方法在 JavaScript Module,但是类似 webpack 的工具会动态绑定
所有的依赖(通过创建依赖图的方式)。这样的好处在于所有的模块都显示声明它们的依赖,避免绑定我们不需要的模块。
webpack 中一个非常酷的功能是可以包含除了 JavaScript 文件之外的任何文件,只需要配置好相应的加载器 loader。这意味着以上那些关于 JavaScript(例如:显示声明)的优点可以用在构建 website 或者 webapp 的各处。现在我们从 CSS 这个可能是你最熟悉的部分开始。
译者注释 : webpack 将各种资源文件统称为 asset,这个词一般指资产,不过资产这个词
过于正式,所以在这里我将统一将 asset 翻译为资源
步骤
在此之前,我们先对我们的项目做一点微调。
dist/index.html
<html>
<head>
- <title>Getting Started</title>
+ <title>Asset Management</title>
</head>
<body>
<script src="./bundle.js"></script>
</body>
</html
加载 CSS
为了import
一个 CSS 文件从 JavaScript 模块,你需要安装然后添加style-loader
和css-loader
到你的module
配置:
npm install --save-dev style-loader css-loader
webpack.config.js
var 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 使用正则表达式去指明需要搜索什么文件,以及如何去加载这些文件。在这里
例子中,所有文件后缀名称为.css
的文件将会被stlye-loader
和css-loader
加载。
上述配置将使你可以用import的方式将'./style.css'
引入你的文件中。现在我们让这个模块运行起来。一个<script>
标签将会被被一段在 html 文件头部的字符串所替代。
现在让我们添加一个新的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, now imported by this script
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> tag,你会看见我们的样式已经被包含在内了。
你甚至可以拆分你的 CSS 文件,以便能在生产环节中更好的决定加载实际。除此之外你
还可以加载 CSS 的变体包括 postcss,sass 或者 less.
加载图片
现在我们可以修改 CSS 了,那么我们如何添加图片作为背景或者图标呢?使用file-loader我们可以很容易的将它们纳入我们的体系中.首先我们按照 file-loader
npm install --save-dev file-loader
webpack.config.js
var 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'
+ ]
+ }
]
}
};
现在,当你从./my-image.png
中引入MyImage
,这个图片将被处理,然后添加到output
目录,并且这个MyImage
变量将包含这个图片被处理后的最终 url。当使用css-loader
,正如所展示的那样,一个类似的处理url('./my-image.png')
的方法会被调用在你的 CSS 中。这个加载器将会识别出这个本地文件,然后替换'./my-image.png'
路径为最终output
文件夹中的目录。html-loader 处理![](./my-image.png)
使用同样的方法。
现在我们添加图片到我们的项目中,看看它是如何工作的,你可以使用任意一张你自己的图片。
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, 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);
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]
如果一切正常的话,你可以看到你的 icon 会作为背景反复出现,与此同时一个img
元素将会出现在Hello webpack
文本后面。如果你审查这些元素,你会看到实际的文件名称已经被该为类似5c999da72346a995e7e2718865d019c8.png
的结构,这意味着 webpack 在src
中找到了我们的文件,并且处理过他们。
一个合理的步骤是压缩和优化你的图片,查看 image-webpack-loader 和 url-loader 的介绍获取更多关于如何优化你的图片处理过程的内容。
加载字体
好!现在我们来看看如何加载字体资源。文件和 url 加载器可以加载任何文件,并且输出到你的构建目录中,任何文件意味着包括字体文件。现在我们更新配置文件去处理字体文件。
webpack.config.js
var 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
使用以上的加载器配置和字体文件,你可以将字体纳入你的项目,使用引用本地文件的url()
命令,你同样可以加载字体文件,就像加载图片一样。
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');
}
现在我们再次构建
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 文件,CSVs,TSVs 和 XML。NodeJS 原生支持对 JSON 文件的支持,这意味着你只需要使用 import Data from './data.json'
命令就可以直接使用了。但是引入 CSVs,TSVs 和 XML 你需要使用csv-loader
和xml-loader
,现在让我们同时加载它们。
npm install --save-dev csv-loader xml-loader
webpack.config.js
var 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)并且数据将被直接解析为 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
文件,你可以在浏览器的开发工具控制台中看到被引入的文件的日志。
(译者注:使用这个加载数据文件的特性,非常有利于测试,可以用这个特性模拟 ajax 请求的数据,有助于前后端同时开始。而不相互等待)