加载 CSS

  • 安装并添加 style-loader 和 css-loader:

    1. npm install --save-dev style-loader css-loader
  • webpack.config.js

    ```javascript const path = require(‘path’);

    module.exports = { entry: ‘./src/index.js’, output: {

    1. filename: 'bundle.js',
    2. path: path.resolve(__dirname, 'dist')

    },

  • module: {
  • rules: [
  • {
  • test: /.css$/,
  • use: [
  • ‘style-loader’,
  • ‘css-loader’
  • ]
  • }
  • ]
  • } }; ```

webpack 根据正则表达式,来确定应该查找哪些文件,并将其提供给指定的 loader。在这种情况下,以 .css 结尾的全部文件,都将被提供给 style-loader 和 css-loader。

  • 通过在项目中添加一个新的 style.css 文件,并将其导入到我们的 index.js 中:

    ``` // project

    webpack-demo |- package.json |- webpack.config.js |- /dist |- bundle.js |- index.html |- /src

  • |- style.css |- index.js |- /node_modules ```
  1. // src/style.css
  2. .hello {
  3. color: red;
  4. }
  1. // src/index.js
  2. import _ from 'lodash';
  3. + import './style.css';
  4. function component() {
  5. var element = document.createElement('div');
  6. // lodash 是由当前 script 脚本 import 导入进来的
  7. element.innerHTML = _.join(['Hello', 'webpack'], ' ');
  8. + element.classList.add('hello');
  9. return element;
  10. }
  11. document.body.appendChild(component());
  1. 运行一下
  2. npm run build

加载图片

  • 安装并添加 file-loader:

    1. npm install --save-dev file-loader
  • webpack.config.js

    ```javascript const path = require(‘path’);

    module.exports = { entry: ‘./src/index.js’, output: {

    1. filename: 'bundle.js',
    2. path: path.resolve(__dirname, 'dist')

    }, module: {

    1. rules: [
    2. {
    3. test: /\.css$/,
    4. use: [
    5. 'style-loader',
    6. 'css-loader'
    7. ]
    8. },
  • {
  • 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 src="./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 ```
  1. // src/index.js
  2. import _ from 'lodash';
  3. import './style.css';
  4. + import Icon from './icon.png';
  5. function component() {
  6. var element = document.createElement('div');
  7. // Lodash,现在由此脚本导入
  8. element.innerHTML = _.join(['Hello', 'webpack'], ' ');
  9. element.classList.add('hello');
  10. + // 将图像添加到我们现有的 div。
  11. + var myIcon = new Image();
  12. + myIcon.src = Icon;
  13. +
  14. + element.appendChild(myIcon);
  15. return element;
  16. }
  17. document.body.appendChild(component());
  1. // src/style.css
  2. .hello {
  3. color: red;
  4. + background: url('./icon.png');
  5. }
  1. 运行一下
  2. npm run build

加载字体

  • file-loader 和 url-loader 可以接收并加载任何文件,然后将其输出到构建目录。这就是说,我们可以将它们用于任何类型的文件,包括字体。

  • webpack.config.js

    ``` const path = require(‘path’);

    module.exports = { entry: ‘./src/index.js’, output: {

    1. filename: 'bundle.js',
    2. path: path.resolve(__dirname, 'dist')

    }, module: {

    1. rules: [
    2. {
    3. test: /\.css$/,
    4. use: [
    5. 'style-loader',
    6. 'css-loader'
    7. ]
    8. },
    9. {
    10. test: /\.(png|svg|jpg|gif)$/,
    11. use: [
    12. 'file-loader'
    13. ]
    14. },
  • {
  • 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 获取处理,就像它处理图片资源一样:

  1. // src/style.css
  2. + @font-face {
  3. + font-family: 'MyFont';
  4. + src: url('./my-font.woff2') format('woff2'),
  5. + url('./my-font.woff') format('woff');
  6. + font-weight: 600;
  7. + font-style: normal;
  8. + }
  9. .hello {
  10. color: red;
  11. + font-family: 'MyFont';
  12. background: url('./icon.png');
  13. }
  1. 运行一下
  2. npm run build

加载字体

  • 此外,可以加载的有用资源还有数据,如 JSON 文件,CSV、TSV 和 XML。类似于 NodeJS,JSON 支持实际上是内置的,也就是说 import Data from './data.json' 默认将正常运行。要导入 CSV、TSV 和 XML,你可以使用 csv-loaderxml-loader。让我们处理这三类文件:

    1. npm install --save-dev csv-loader xml-loader
  • webpack.config.js

    ``` const path = require(‘path’);

    module.exports = { entry: ‘./src/index.js’, output: {

    1. filename: 'bundle.js',
    2. path: path.resolve(__dirname, 'dist')

    }, module: {

    1. rules: [
    2. {
    3. test: /\.css$/,
    4. use: [
    5. 'style-loader',
    6. 'css-loader'
    7. ]
    8. },
    9. {
    10. test: /\.(png|svg|jpg|gif)$/,
    11. use: [
    12. 'file-loader'
    13. ]
    14. },
    15. {
    16. test: /\.(woff|woff2|eot|ttf|otf)$/,
    17. use: [
    18. 'file-loader'
    19. ]
    20. },
  • {
  • 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 ```
  1. // src/data.xml
  2. <?xml version="1.0" encoding="UTF-8"?>
  3. <note>
  4. <to>Mary</to>
  5. <from>John</from>
  6. <heading>Reminder</heading>
  7. <body>Call Cindy on Tuesday</body>
  8. </note>

现在,你可以 import 这四种类型的数据(JSON, CSV, TSV, XML)中的任何一种,所导入的 Data 变量将包含可直接使用的已解析 JSON:

  1. // src/index.js
  2. import _ from 'lodash';
  3. import './style.css';
  4. import Icon from './icon.png';
  5. + import Data from './data.xml';
  6. function component() {
  7. var element = document.createElement('div');
  8. // Lodash, now imported by this script
  9. element.innerHTML = _.join(['Hello', 'webpack'], ' ');
  10. element.classList.add('hello');
  11. // Add the image to our existing div.
  12. var myIcon = new Image();
  13. myIcon.src = Icon;
  14. element.appendChild(myIcon);
  15. + console.log(Data);
  16. return element;
  17. }
  18. document.body.appendChild(component());

当打开 index.html 并查看开发者工具中的控制台,能够看到导入的数据打印在上面。

在使用 d3 等工具来实现某些数据可视化时,预加载数据会非常有用。我们可以不用再发送 ajax 请求,然后于运行时解析数据,而是在构建过程中将其提前载入并打包到模块中,以便浏览器加载模块后,可以立即从模块中解析数据。

全局资源

上述所有内容中最出色之处是,以这种方式加载资源,你可以以更直观的方式将模块和资源组合在一起。无需依赖于含有全部资源的 /assets 目录,而是将资源与代码组合在一起。例如,类似这样的结构会非常有用:

  1. - |- /assets
  2. + |– /components
  3. + | |– /my-component
  4. + | | |– index.jsx
  5. + | | |– index.css
  6. + | | |– icon.svg
  7. + | | |– img.png

这种配置方式会使你的代码更具备可移植性,因为现有的统一放置的方式会造成所有资源紧密耦合在一起。假如你想在另一个项目中使用 /my-component,只需将其复制或移动到 /components 目录下。只要你已经安装了任何扩展依赖(external dependencies),并且你已经在配置中定义过相同的 loader,那么项目应该能够良好运行。

但是,假如你无法使用新的开发方式,只能被固定于旧有开发方式,或者你有一些在多个组件(视图、模板、模块等)之间共享的资源。你仍然可以将这些资源存储在公共目录(base directory)中,甚至配合使用 alias 来使它们更方便 import 导入