在开始接下来的教程之前,你应该已经有一个展示“Hello webpack”的小工程了。现在我们来尝试合并一些其他资源,例如图片,看看该如何处理它们。
在webpack之前,前端开发人员会使用类似grunt和gulp之类的工具处理这些资源,并把它们从src目录移到dist或build目录中。但类似webpack这样的工具会动态捆绑所有的依赖关系(创建依赖图),相同的想法也用在了Javascript模块上。这样做非常好,因为每个模块都明确指明它的依赖状态,而且我们还可以避免加载不需要的模块。
webpack最酷的一个特性就是除了Javascript之外, 你可以通过一个加载器包含任何类型的文件。这意味着上述列举的有关JavaScript的好处(例如显示依赖关系),都可以应用于构建网站或Web应用程序时使用的所有内容。通过前面的教程你应该已经熟悉了该设置,让我们先从CSS开始吧。
设置
- 在开始之前,我们做一点点改变先:
dist/index.html
- Getting Started
+ Asset Management
加载 CSS
- 为了在JavaScript模块中import一个CSS文件,你需要安装并添加style-loader和css-loader到你配置文件的module中:
npm install style-loader css-loader --save-dev
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 使用正则表达式来确定它应该查找哪些文件并对其使用特定加载器。在这个例子中,任何以.css结尾的文件都将使用style-loader和css-loader加载器。
这样就允许通过imort "./style.css"导入文件并使用其中的样式。现在当模块运行的时候,一个字符串化的标签就会添加到你的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
在浏览器中打开index.html就可以看到红色的Hello webpack了。可以通过检查页面查看 head 标签。里面有我们导入到index.js中的样式块。
注意,你可以(在大多数情况下)压缩css代码,以便在生产环境中节省更多的加载时间。最重要的是,加载器几乎存在于你能想到的任何CSS风格中--postcss,sass,以及less等等。
加载图片
- 我们已经可以把CSS加入到我们的项目中了,那我们背景图和图标呢?使用file-loader可以很轻易的就整合进我们的系统:
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'的时候, 该图片将被处理并添加到输出目录中,而且变量MyImage将包含处理后该图片的最终url。当使用css-loader时, 如上所示,CSS中的url('./my-image.png')也会出现类似的过程。加载器会识别出这是本地文件,并将路径'./my-image.png'替换为输出目录中图片的最终路径。html-loader也用相同的方式处理**。
- 让我们添加任何一张你喜欢的图片到我们的项目中:
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
- 如果一切正常,你会看到你的图片成为了重复的背景,以及Hello webpack文字旁边的img元素。如果你检查元素,你会看到实际的文件名是类似于82b9c7a5a3f405032b1db71a25f67021.png的。这意味着webpack找到了我们在src目录下的图片并进行了处理。
这里合乎逻辑的下一步是缩小和优化您的图像。查看image-webpack-loader和url-loader,了解有关如何增强图像加载过程的更多信息。
加载字体
- 那么像字体这样的资源的?文件和url加载器会获取你通过它们加载的任何文件,并将其输出到构建目录。这意味着我们可以使用它们处理任何类型的文件,包括字体文件。
- 现在更新一下webpack.confog.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
- 配置和添加好字体后,你可以使用@font-face申明来合并它们。webpack将会使用过本地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');
}
- 现在重新构建并打开index.html文件:
npm run build
- 你会看到Hello webpack换了一种字体。
加载数据
- 另一种可以被加载的有用资源是数据,像JSON,CSV,TSV和XML文件。对JSON文件的支持是内置的,和NodeJs一样,意味着可以直接使用import Data from './data.json。为了importCSV,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'
+ ]
+ }
]
}
};
- 添加一个xml文件
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
Mary
John
Reminder
Call Cindy on Tuesday
- 现在你可以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目录即可。只要你安装了任何外部依赖项并且配置文件定义了相同的加载器,那就没问题了。
但是,假设你已经锁定了老的方式或者有一些资源在多个组件中共享(views,templates,modules等等)。仍然可以将这些资源放在基目录中,甚至可以使用别名使它们更容易import。
总结
- 因为下一节Output Management不需要这节中使用所有资源, 所以在进入到下一节之前我们做一些清理工作。
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, 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());