webpack 静态资源管理
对于 js 资源,基于JavaScript模块,webpack 将动态捆绑所有依赖项(创建所谓的依赖图)。 这很好,因为现在每个模块都明确声明了它的依赖关系,这样可以避免捆绑未使用的模块。
webpack 的 loader
可以给项目的静态资源带来同样的功能。
以配置 css 资源为起点,来展开 webpack 对静态资源的配置。
载入 CSS 资源
修改一下之前的项目:
# dist/index.html
<!doctype html>
<html>
<head>
- <title>Getting Started</title>
+ <title>Asset Management</title>
</head>
<body>
- <script src="./main.js"></script>
+ <script src="./bundle.js"></script>
</body>
</html>
# webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
- filename: 'main.js',
+ filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
Loadi
复制代码
配置 loader
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
。
这使您可以将./style.css
导入到依赖于该样式的文件中。 现在,当运行bundle.js
时,会将对应的 css 通过<style>
标签将插入到html文件的<head>
中。
安装依赖
npm install --save-dev style-loader css-loader
复制代码
添加 css 代码到项目中
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
# npx webpack
复制代码
请检查页面(不要查看页面源,因为它不会显示结果)并查看页面的head标签。 它应该包含我们在index.js
中导入的样式块。
tips:
请注意,您可以(在大多数情况下)最小化css,以便在生产中获得更好的加载时间。 最重要的是,加载器几乎存在于你能想到的任何CSS风格 - postcss,sass, less等等。
载入 images 资源
安装依赖
npm install --save-dev file-loader
复制代码
修改一下之前的项目
webpack-demo
|- package.json
|- webpack.config.js
|- /dist
|- bundle.js
|- index.html
|- /src
+ |- icon.png
|- style.css
|- index.js
|- /node_modules
# src/style.css
.hello {
color: red;
+ background: url('./icon.png');
}
# 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());
# 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'
+ ]
+ }
]
}
};
复制代码
现在,当您从./my-image.png
导入 MyImage 时,该图像将被处理并添加到您的输出目录中,并且 MyImage 变量将包含处理后该图像的最终 URL。 当使用css-loader
时,如上所示,CSS 中的url('./ my-image.png')
将发生类似的过程。 加载程序将识别这是一个本地文件,并将./my-image.png
路径替换为输出目录中图像的最终路径。 html-loader
以相同的方式处理<img src =“./ my-image.png”/>
。
编译
npm run build
# npx webpack
复制代码
如果一切顺利,您现在应该将您的图标视为重复背景,以及我们的Hello webpack文本旁边的img元素。 如果检查此元素,您将看到实际文件名已更改为5c999da72346a995e7e2718865d019c8.png
。 这意味着webpack在src文件夹中找到了我们的文件并进行了处理!
tips :
下一步是缩小和优化您的图像。 查看image-webpack-loader和url-loader,了解有关如何增强图像加载过程的更多信息。
载入 Fonts
那么像字体这样的其他资产呢? 文件和URL加载器将获取您通过它们加载的任何文件,并将其输出到您的构建目录。 这意味着我们可以将它们用于任何类型的文件,包括字体。 让我们更新我们的webpack.config.js
来处理字体文件:
修改项目
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
# 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'
+ ]
+ }
]
}
};
复制代码
载入 Data
可以加载的另一个有用资产是数据,如JSON文件,CSV,TSV和XML。 对JSON的支持实际上是内置的,类似于 NodeJS,这意味着import Data from'./data.json'
导入数据默认情况将起作用。 要导入CSV,TSV和XML,您可以使用csv-loader和xml-loader
。 让我们处理所有三个:
安装依赖
npm install --save-dev csv-loader xml-loader
复制代码
修改项目
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>
# 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());
# 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'
+ ]
+ }
]
}
};
复制代码
现在,您可以导入这四种类型的数据中的任何一种(JSON,CSV,TSV,XML),并且导入它的Data变量将包含已解析的JSON以便于使用。
全局资源 Global Assets
上述所有内容中最酷的部分是,以这种方式加载资产允许您以更直观的方式将模块和资产组合在一起。 您可以使用它们的代码对资产进行分组,而不是依赖包含所有内容的全局/资产目录。 例如,像这样的结构非常有用:
修改项目
- |- /assets
+ |– /components
+ | |– /my-component
+ | | |– index.jsx
+ | | |– index.css
+ | | |– icon.svg
+ | | |– img.png
复制代码
这种设置会更加的方便,因为现在组件所有内容都紧密耦合。 假设你想在另一个项目中使用/ my-component,只需复制或移动到那里的/ components目录即可。 只要有相同的 webpack 配置和 依赖就可以了。
但是,假设您已陷入旧方式,或者您拥有多个组件(视图,模板,模块等)之间共享的资产。 仍然可以将这些资产存储在基本目录中,甚至可以使用别名来使它们更容易导入。
NEXT
对于下一个指南,我们不会使用我们在本指南中使用的所有不同资产,所以让我们做一些清理,以便我们为下一部分指南输出管理做好准备:
修改项目
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());
复制代码