Skip to content

Latest commit

 

History

History
257 lines (204 loc) · 8.57 KB

File metadata and controls

257 lines (204 loc) · 8.57 KB

本节将探讨如何使用file-loaderurl-loader打包图片和SVG等资源。

本文项目最终结构如下所示:

Project
  |--buildOutput
  |--images
  |  |--npm.svg (0.24KB)
  |  |--github.png (6.17KB)
  |  |--star.png (9.14KB)
  |  |--webpack.png (52.7KB)
  |
  |--node_modules
  |--.babelrc
  |--index.html
  |--index.js
  |--index.css
  |--package.json
  |--README.md
  |--webpack.config.js

index.html如下所示:

<!DOCTYPE html>
<html>

<head>
    <title>Webpack</title>
</head>

<body>
    <div id="star"></div>
</body>
<script type="text/javascript" src="buildOutput/bundle.js"></script>

</html>

index.css文件如下所示:

#star {
    width: 48px;
    height: 48px;
    background: url(images/star.png) no-repeat center;
}

img {
    display: block;
    max-width: 250px;
}

我们在index.css中设置了#star的背景是star.png

index.js文件如下所示:

import "./index.css";

import githubPng from "./images/github.png";// <=> const github = require("./images/github.png");
import webpackPng from "./images/webpack.png";// <=> const webpack = require("./images/webpack.png");
import npmSvg from "./images/npm.svg";// <=> const npmSvg = require("./images/npm.svg");

const img1 = document.createElement("img");
img1.src = githubPng;
document.body.appendChild(img1);
console.log(githubPng);

const img2 = document.createElement("img");
img2.src = webpackPng;
document.body.appendChild(img2);
console.log(webpackPng);

const img3 = document.createElement("img");
img3.src = npmSvg;
document.body.appendChild(img3);
console.log(npmSvg);

我们在index.js中通过import(或require())加载了github.pngwebpack.pngnpm.svg,根据这些资源创建了相应的DOM,并输出了资源的路径。

为了能够在Webpack中使用这些图片资源文件,我们需要使用file-loaderfile-loader的作用不是把图片等文件打包到一个JavaScript文件中,而是通过file-loader方便地获得要使用的图片等资源的URL。

首先我们要安装file-loader

npm install --save-dev file-loader

webpack.config.js配置如下所示:

var path = require("path");

var buildFolder = "buildOutput";

module.exports = {
    entry: "./index.js",

    output: {
        path: path.join(__dirname, buildFolder),
        filename: "bundle.js"
    },

    module: {
        loaders: [{
            test: /\.js$/,
            loader: 'babel-loader'
        }, {
            test: /\.(jpg|jpeg|png|svg)$/,
            loader: 'file-loader'
        }, {
            test: /\.css$/,
            loader: 'style!css'
        }]
    }
};

对于图片和SVG文件,我们需要使用file-loader进行加载。

运行npm start进行打包,在buildOutput目录下输出结果如下所示:

我们可以看到,图片和SVG的文件名变成了hash值,默认情况下,file-loader使用文件的hash值作为文件名。需要注意的是,这些图片文件没有打包到bundle.js中。file-loader的作用不是把图片等文件打包到一个JavaScript文件中,而是通过file-loader方便地获得要使用的图片等资源的URL。

我们双击打开index.html文件,发现界面上没有显示任何图片,图片加载不成功肯定是URL路径不对。我们在index.js中将这几个图片和SVG的路径进行了输出,我们打开控制台,输出如下:

index.htmlbuildOutput目录之间的相对位置如下所示:

Project
  |
  |--index.html
  |--buildOutput
      |--30b63bc34b872b05319d23070d29ff31.png
      |--0714810ae3fb211173e2964249507195.png
      |--ab8d3852300ee8fce6ce89d0a1b2a362.svg
      |--009911f7665c7be361e829ea741b70eb.png

由此可见,在运行时,index.html中使用了错误的URL路径,应该将路径改为buildOutput/30b63bc34b872b05319d23070d29ff31.png等。

为了解决URL路径问题,我们修改webpack.config.js,为output节点配置publicPath属性,配置如下:

var path = require("path");

var buildFolder = "buildOutput";

module.exports = {
    entry: "./index.js",

    output: {
        path: path.join(__dirname, buildFolder),
        filename: "bundle.js",
        publicPath: buildFolder + "/"
    },

    module: {
        loaders: [{
            test: /\.js$/,
            loader: 'babel-loader'
        }, {
            test: /\.(jpg|jpeg|png|svg)$/,
            loader: 'file-loader'
        }, {
            test: /\.css$/,
            loader: 'style!css'
        }]
    }
};

我们为配置了output.publicPath的值为buildFolder + "/",我们执行npm start再次执行打包,刷新index.html页面,这次控制台输出如下所示:

这次URL输出路径是正确的,界面也能正确显示所有的图片,如下所示:

我们之前提到file-loader不能将文件打包到JavaScript的输出文件中,我们想把一些比较小的图片打包到bundle.js中,这时我们可以使用url-loader

我们安装url-loader

npm install --save-dev url-loader

我们可以把url-loader看做是file-loader的升级版,url-loader除了可以方便地获取图片等资源的URL路径,还可以选择性地将图片等资源打包到输出的JavaScript文件中,这样可以减少小文件的请求数量。url-loader依赖file-loader,在使用url-loader时,请确保已安装了file-loader

我们修改webpack.config.js,如下所示:

var path = require("path");

var buildFolder = "buildOutput";

module.exports = {
    entry: "./index.js",

    output: {
        path: path.join(__dirname, buildFolder),
        filename: "bundle.js",
        publicPath: buildFolder + "/"
    },

    module: {
        loaders: [{
            test: /\.js$/,
            loader: 'babel-loader'
        }, {
            test: /\.(jpg|jpeg|png|svg)$/,
            loader: 'url-loader', //url-loader?limit=10000
            query: {
                limit: 10 * 1024 //10KB
            }
        }, {
            test: /\.css$/,
            loader: 'style!css'
        }]
    }
};

我们用url-loader替换了file-loader,并且通过

query: {
    limit: 10 * 1024 //10KB
}

url-loader配置了limit参数为10KB,也可以通过url-loader?limit=10000的形式为其指定limit等参数。如果不配置limit参数,那么url-loader会将index.js中用到的所有图片和资源打包到buildOutput/bundle.js中。我们此处配置limit参数为10KB,url-loader只会将10KB以下的图片等资源打包到buildOutput/bundle.js中,超过10KB的图片只是拷贝到buildOutput目录下(当然,文件名会改成hash)。

重新执行npm start进行打包,在buildOutput目录下输出结果如下所示:

github.pngstar.pngnpm.svg都小于10KB,这三个文件被打包到了buildOutput/bundle.js中,而webpack.png大于10KB,所以没有被打包到buildOutput/bundle.js中。

刷新index.html页面,依然能正确显示图片,控制台输出如下:

由此可以看出,github.pngnpm.svg已经被打包成了base64字符串存储在bundle.js中了。