Webpack5 系列(二):静态资源的处理2

简介: Webpack5 系列(二):静态资源的处理2

2. 配置静态文件名

默认情况下,打包以后的文件是散在 dist 文件夹中的,难以区分和维护。

现在,需要将他们分门别类地放进对应的文件夹中,就需要对文件名做统一的管理。

webpack.config.js


const path = require("path");
const miniSVGDataURI = require("mini-svg-data-uri");
module.exports = {
  mode: "production",
  entry: {
    main: "./src/index.js",
  },
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js",
    // 静态文件打包后的路径及文件名(默认是走全局的,如果有独立的设置就按照自己独立的设置来。)
    assetModuleFilename: "assets/[name]_[hash][ext]",
  },
  module: {
    rules: [
      // 图片文件
      {
        test: /\.(jpe?g|png|gif)$/i,
        type: "asset",
        generator: {
          filename: "images/[name]_[hash][ext]", // 独立的配置
        },
      },
      // svg 文件
      {
        test: /\.svg$/i,
        type: "asset",
        generator: {
          dataUrl(content) {
            content = content.toString();
            return miniSVGDataURI(content);
          },
        },
      },
      // 字体文件
      {
        test: /\.(otf|eot|woff2?|ttf|svg)$/i,
        type: "asset",
        generator: {
          filename: "fonts/[name]_[hash][ext]",
        },
      },
      // 数据文件
      {
        test: /\.(txt|xml)$/i,
        type: "asset/source", // exports the source code of the asset
      },
    ],
  },
};

第 23 - 25 行,用于单独配置静态文件名;

generator: {
  filename: 'images/[name]_[hash][ext]' // 单独配置打包的路径及文件名
},

第 12 行,assetModuleFilename: 'assets/[name][ext]', 用于设置全局的静态文件路径及文件名。如果文件模块没有单独进行配置,就按照这个来设置文件名。

其中,[name] 表示原来的文件名,[hash] 表示散列值,[ext] 表示文件后缀。这些都属于占位符(placeholders),在 webpack4 中有提到:v4.webpack.js.org/loaders/fil…

3. asset 类型

当 type 设置为'asset',就会按照以下的策略去打包文件:

  • 如果一个模块大小超过 8 kb(这个值是默认的),就使用 asset/resource,被打包进输出文件夹中。(类似于 file-loader)
  • 否则,就使用 asset/inline,内联到打包文件中。(类似于 url-loader)

区别在于:前者会被单独放进输出文件夹中,后者被处理成 base64 编码字符串内敛进打包出的 JS 文件中。

后者的好处在于减少一次 http 请求,但是过长的字符串也会加重 js 的体积导致加载变慢,因此需要根据实际情况来确定到底采用哪一种方式去处理文件。

注意,当被作为后者处理时,是可以设置编码方式的,例如上面提到的特殊处理。

手动通过 Rule.parser.dataUrlCondition.maxSize 去设置两者的界限:

{
  test: /\.(jpe?g|png|gif)$/i,
  type: 'asset',
  generator: {
    filename: 'images/[name]_[hash][ext]',
  },
  parser: {
    dataUrlCondition: {
      maxSize: 8 * 1024 // 8kb (低于8kb都会压缩成 base64)
    }
  },
},
{
  test: /\.svg$/i,
  type: 'asset',
  generator: {
    filename: 'icons/[name]_[hash][ext]',
    dataUrl(content) {
      content = content.toString();
      return miniSVGDataURI(content); // 通过插件提供的编码算法处理文件
    }
  },
  parser: {
    dataUrlCondition: {
      maxSize: 2 * 1024 // 2kb (低于2kb都会压缩)
    }
  },
},

另外,除了asset/resourceasset/inline,还有一个上文提到的,用于处理 txt、xml 文件的asset/source,它相当于 webpack4 的 raw-loader。

三、样式文件的处理

1. style-loader & css-loader

style-loader 和 css-loader 是相辅相成的。

  • style-loader:将 <style> 标签插入到 DOM 中。
  • css-loader:解析通过 @import、url()、import/require() 这些方式引入的样式文件。

安装 loaders:

npm install --save-dev css-loader style-loader

webpack.config.js

module.exports = {
  module: {
    rules: [
      // ...
      {
        test: /\.css$/i,
        use: ["style-loader", "css-loader"],
      },
    ],
  },
};

注意两个 loader 的位置,要反过来写。

index.js

// ...
const reset = require("./assets/styles/reset.css");
console.log("css: ", reset);
import "./assets/styles/reset.css";
const dom = document.getElementById("root");
dom.innerHTML += '<p class="iconfont icon-mianxingshezhi">This a text.</p>';

reset.css

@font-face {
  font-family: "iconfont";
  /* Project id 1947684 */
  src: url("../fonts/iconfont.woff2?t=1627306378388") format("woff2"), url("../fonts/iconfont.woff?t=1627306378388") format("woff"),
    url("../fonts/iconfont.ttf?t=1627306378388") format("truetype");
}
.iconfont {
  font-family: "iconfont" !important;
  font-size: 16px;
  font-style: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
.icon-mianxingshezhi:before {
  content: "\e6ad";
}
/* ... */

解释:reset.css 中引入了字体图标(来自 iconfont),index.js 中通过import的方式引入了这个 css 文件,并使用了这个字体图标。

其中,

import './assets/styles/reset.css'

onst reset = require('./assets/styles/reset.css');

这两段语句背后的 CSS 代码就是通过 css-loader 去解析的。

控制台展示如下:

1688267754134.png


上图中,在 CSS 样式被 css-loader 解析完成后, <style> 标签通过 style-loader 插入到 DOM 中。

2. sass-loader

  • sass-loader:加载一个 Sass/SCSS 文件,并编译成 CSS。

安装:

npm install sass-loader sass webpack --save-dev

webpack.config.js

module.exports = {
  module: {
    rules: [
      // ...
      {
        test: /\.s[ac]ss$/i,
        use: [
          // Creates `style` nodes from JS strings
          "style-loader",
          // Translates CSS into CommonJS
          "css-loader",
          // Compiles Sass to CSS
          "sass-loader",
        ],
      },
    ],
  },
};

index.js

const global = require("./assets/styles/global.scss");
console.log("scss: ", global);
import "./assets/styles/global.scss";
const dom = document.getElementById("root");
// insert an image
const img = new Image();
img.src = dog1;
// img.width = 200;
img.classList.add("avatar");
root.append(img);

global.scss

// 自定义变量
$color: #ff4200;
$fs: 14px;
$ls: 1.2;
// 自定义mixin
@mixin size($w, $h: $w) {
  width: $w;
  height: $h;
}
body {
  font-size: $fs;
  background-color: #eaeaea;
  .avatar {
    @include size(150px);
    transform: translateX(50px);
  }
}

控制台展示如下:

1688267862250.png

上图第二个 <style> 标签内的样式代码就是 global.scss 中转译成 css,并通过 style-loader 插入到 DOM 中的。

目录
相关文章
|
前端开发 JavaScript
Webpack5 系列(二):静态资源的处理4
Webpack5 系列(二):静态资源的处理4
228 0
|
前端开发 JavaScript Shell
Webpack5 系列(二):静态资源的处理3
Webpack5 系列(二):静态资源的处理3
200 0
|
XML 前端开发 JavaScript
Webpack5 系列(二):静态资源的处理1
Webpack5 系列(二):静态资源的处理
345 0
|
缓存 前端开发 JavaScript
Webpack 打包的基本原理
【10月更文挑战第5天】
|
前端开发 JavaScript
ES6模块化和webpack打包
【10月更文挑战第5天】
|
JavaScript
webpack打包TS
webpack打包TS
232 60
|
JavaScript 测试技术 Windows
vue配置webpack生产环境.env.production、测试环境.env.development(配置不同环境的打包访问地址)
本文介绍了如何使用vue-cli和webpack为Vue项目配置不同的生产和测试环境,包括修改`package.json`脚本、使用`cross-env`处理环境变量、创建不同环境的`.env`文件,并在`webpack.prod.conf.js`中使用`DefinePlugin`来应用这些环境变量。
1154 2
vue配置webpack生产环境.env.production、测试环境.env.development(配置不同环境的打包访问地址)
|
缓存 前端开发 JavaScript
深入了解Webpack:模块打包的革命
【10月更文挑战第11天】深入了解Webpack:模块打包的革命
|
前端开发 开发者
在前端开发中,webpack 作为一个强大的模块打包工具,为我们提供了丰富的功能和扩展性
【9月更文挑战第1天】在前端开发中,Webpack 作为强大的模块打包工具,提供了丰富的功能和扩展性。本文重点介绍 DefinePlugin 插件,详细探讨其原理、功能及实际应用。DefinePlugin 可在编译过程中动态定义全局变量,适用于环境变量配置、动态加载资源、接口地址配置等场景,有助于提升代码质量和开发效率。通过具体配置示例和注意事项,帮助开发者更好地利用此插件优化项目。
195 13
|
缓存
webpack 打包多页面应用
webpack 打包多页面应用
149 2