轻装上阵:Webpack 5 & Vite资源优化

  • 作者简介:大家好,我是文艺理科生Owen,某车企前端开发,负责AIGC+RAG项目
  • 目前在卷的技术方向:工程化系列,主要偏向最佳实践
  • 希望可以在评论区交流互动,感谢支持~~~

上一篇我们从0开始构建了webpack的最小化项目,分别举例说明了ES6语法、css语法、typescript语法和tsx语法的编译转换。

在实际的项目开发中,存在多种类型的静态文件,如图片、文本文件、字体文件等。在webpack4中,需要引入对应的loader去逐个解决。但在webpack5中,有更为简便的使用方式。相应的,文章后面也会列举vite的静态资源模块的最佳实践。

webpack5中处理资源模块

静态资源模块(Asset Modules)

回顾webpack4中,处理静态资源需要使用 raw-loader、url-loader、file-loader等。但在webpack5中,可以使用内置的静态资源模块更方便地处理静态资源。

其中有4种静态资源模块类型。

webpack5 用途 替代webpack4的loader名称
asset/resource 导出静态资源的独立文件到输出目录中,并导出独立文件的url file-loader
asset/inline 导出静态资源的data URI url-loader
asset/source 导出静态资源的源代码 raw-loader
asset 在 导出静态资源的 data URI单独文件 自动选择 url-loader

接着上一篇文章的 demo,稍作一些修改,当前目录为:

├─ package.json
├─ pnpm-lock.yaml
├─ README.md
├─ src
│  ├─ index.js
│  └─ index.txt
└─ webpack.config.js

// index.txt
webpack
// package.json
{
    
    
  "name": "demo",
  "version": "1.0.0",
  "description": "V6.0.0 从零到一搭建项目脚手架,梳理工程化中构建的来龙去脉",
  "main": "index.js",
  "scripts": {
    
    
    "dev": "webpack --mode development --config webpack.config.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    
    
    "webpack": "^5.91.0",
    "webpack-cli": "^5.1.4"
  },
  "browserslist": "> 0.05%, not dead"
}
// webpack.config.js
const path = require('path')

module.exports = {
    
    
  mode: 'development',
  entry: './src/index.js',
  output: {
    
    
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
    clean: true
  }
}

我们看到在src目录下新建了一个txt文件,并且在入口文件index.js中引入了txt文件。默认情况下,运行pnpm dev命令打包后,发现 index.txt文件内容会作为字符串嵌入到输出的bundle.js中。

输出独立文件

修改webpack配置,对txt文件采用asset/resource类型处理。

// webpack.config.js
module.exports = {
+  module: {
+    rules: [
+      {
+        test: /.txt$/,
+        type: 'asset/resource' // 对txt文件采用asset/resource类型处理
+      }
+    ]
+  }
}

运行pnpm dev命令打包后,发现 在输出目录中 直接输出了txt独立文件,并在bundle文件中带出了该独立文件的url。

输出data URI

修改webpack配置,对txt文件采用asset/inline类型处理。

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /.txt$/,
-        type: 'asset/resource'
+        type: 'asset/inline' // 对txt文件采用asset/inline类型处理
      }
    ]
  }
}

运行pnpm dev命令打包后,发现在bundle文件中直接生成了base64地址。

输出源代码

修改webpack配置,对txt文件采用asset/source类型处理。

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /.txt$/,
-        type: 'asset/inline'
+        type: 'asset/source' // 对txt文件采用asset/source类型处理
      }
    ]
  }
}

运行pnpm dev命令打包后,发现在bundle文件中直接采用module.exports导出了文本内容。

这里需要说明一下:

默认不加配置时,也是作为asset/source类型转为文本内容,但只是作为字符串嵌入,未对外导出。

显式配置为asset/source后,会把txt当做一个模块,使用module.exports导出文本内容,供其他模块使用。

输出独立文件 vs 输出data URI

修改webpack配置,对txt文件采用asset类型处理。

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /.txt$/,
-        type: 'asset/source'
+        type: 'asset' // 对txt文件采用asset类型处理
      }
    ]
  }
}

运行pnpm dev命令打包后,发现txt文件是以data URI形式导出的。

默认规则是:小于8kb的文件将被视为 inline 模块类型,否则将被视为 resource 模块类型。

我们在webpack配置中修改一下分界的大小(1Byte):

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /.txt$/,
-        type: 'asset'
+        type: 'asset', // 对txt文件采用asset类型处理
+        parser: {
+           dataUrlCondition: {
+            maxSize: 1 // 1byte
+           }
+        }
      }
    ]
  }
}

运行pnpm dev命令打包后,发现txt文件是单独文件的形式导出的。

总结一下:webpack5直接通过对应的type类型设置文件导出的形式。

Vite中处理资源模块

输出独立文件 vs 输出data URI

为了更好地理解vite打包处理资源模块,这里不使用cli方式,继续在项目中演示。可能有小伙伴会问,webpack和vite能在一个项目中共存吗?项目中是不会这么使用的,但对于一个demo来说,只要区分使用命令,就不会有影响。

首先安装vite:pnpm i vite -D,创建vite构建命令

// package.json
{
  "name": "demo",
  "version": "1.0.0",
  "description": "V6.0.1 webpack5和vite如何处理资源模块",
  "main": "index.js",
  "scripts": {
    "dev": "webpack --mode development --config webpack.config.js",
+   "build": "vite build"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^5.91.0",
    "webpack-cli": "^5.1.4",
+    "vite": "5.2.11"
  },
  "browserslist": "> 0.05%, not dead"
}

在根目录下创建vite配置文件vite.config.js

// vite.config.js
export default {
    
    
}

可以看到这里没有指明entry(入口文件),是因为vite基于ESM规范,也就是采用script标签中的type=module进行打包构建。所以需要在根目录下新建一个index.html,并且script的src属性指向入口文件:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script type="module" src="/src/index.js"></script>
</body>
</html>

运行pnpm build命令打包后,发现txt文件是以data URI的形式导出的。

与webpack类似,导出 独立文件 或 data URI形式是按文件大小自动选择的。vite中是通过 assetsInlineLimits属性设置(默认为4kB)。但不同的是,在vite中当静态资源超过assetsInlineLimits值时,即使采用了内联语法(?inline)后,依然不会强制生成data URI形式。

修改一下vite配置:

// vite.config.js
export default {
    
    
  build: {
    
    
    assetsInlineLimit: 1 // 1个字节
  }
}

运行pnpm build命令打包后,发现txt文件是以独立文件的形式导出的。

输出源代码

修改index.js文件:

- import text from './index.txt'
+ import text from './index.txt?raw'

console.log(text);

运行pnpm build命令打包后,发现txt文件是以文本字符串的形式直接嵌入的。

总结:本文通过一个最小的Webpack和vite项目demo,举例演示了在webpack5中采用内置属性将静态资源模块以不同形式导出,并且说明了在vite中如何处理静态资源模块。

demo源码:github

日拱一卒,功不唐捐。

猜你喜欢

转载自blog.csdn.net/m0_46259935/article/details/138473087