【JS】Webpack 5 新特性尝鲜

Webpack 5 新特性尝鲜

西岭老湿发布于 今天 03:37

安装与启动

Webpack 5 发布已经有一段时间了,很多小伙伴都在考虑要不要升级,有没有升级的必要,不知道升级后有哪些改变;
今天我们就来做个对比看看,webpack5 带来了那些全新的改变;
没有对比就没有伤害,为了更好地伤害 webpack 4 , 我们使用 webpack4 和 webpack 5 分别构建一个 React 项目来做对比:

mkdir webpack4

mkdir webpack5

# 分别执行 初始化命令

npm init -y

创建文件 /src/index.js, /src/App.js, /src/index.html

React 代码示例
index.js

import React from "react"

import ReactDom from "react-dom"

import App from "./App"

ReactDom.render(,document.getElementById('root'))

App.js
【JS】Webpack 5 新特性尝鲜

index.html

<!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>

<!-- 加一行注释 -->

<div id="root"></div>

</body>

</html>

安装与启动

webpack4

// webpack4

npm install [email protected] [email protected] html-webpack-plugin css-loader style-loader babel-loader @babel/core @babel/preset-env @babel/preset-react -D

npm install react react-dom

因为仓库中目前默认就已经是 webpack5 了,所以,想要安装 webpack4, 我们需要加上 @4 的版本号;

webpack5

// webpack5

npm install webpack webpack-cli html-webpack-plugin css-loader style-loader babel-loader @babel/core @babel/preset-env @babel/preset-react -D

npm install react react-dom

基础配置 webpack.config.js

const path = require('path')

const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {

// entry 入口,output出口,module模块,plugins 插件 mode工作模式,devServer开发服务器

// mode 工作模式

mode: 'development', // production 、 development、none

// 入口

entry:'./src/index.js',

// 出口

output:{

filename:'./bundle.js',

path:path.resolve(__dirname,'dist')

},

// 模块

module:{

rules:[

{

test:/\.js$/,

exclude:/node_modules/,

use:[

{

loader:'babel-loader',

options:{

presets:[

'@babel/preset-env',

'@babel/preset-react'

]

}

}

]

},

]

},

// 插件

plugins:[

new HtmlWebpackPlugin({

template:'./src/index.html'

})

]

}

启动命令的区别
先安装 npm install webpack-dev-server -D
配置服务器:

  //  服务器

devServer:{

port:3004,

open:true

},

webpack 4 : webpack4/package.json

"scripts": {

"test": "echo \"Error: no test specified\" && exit 1",

"build": "webpack",

"start": "webpack-dev-server"

},

webpack 5 : webpack5/package.json

 "scripts": {

"test": "echo \"Error: no test specified\" && exit 1",

"build":"webpack",

"start":"webpack serve"

},

资源模块处理

https://webpack.docschina.org/guides/asset-modules/#source-assets

资源模块(asset module)是一种模块类型,它允许使用资源文件(字体,图标等)而无需配置额外 loader。

在 webpack 5 之前,通常使用:

  • raw-loader 将文件导入为字符串

  • url-loader 将文件作为 data URI 内联到 bundle 中

  • file-loader 将文件发送到输出目录

资源模块类型(asset module type),通过添加 4 种新的模块类型,来替换所有这些 loader:

  • asset/resource 发送一个单独的文件并导出 URL(之前通过使用 file-loader 实现)
  • asset/inline 导出一个资源的 data UR(之前通过使用 url-loader 实现)
  • asset/source 导出资源的源代码(之前通过使用 raw-loader 实现)
  • asset 在导出一个 data URI 和发送一个单独的文件之间自动选择(之前通过使用 url-loader,并且配置资源体积限制实现)

webpack4 :

  // 模块

module:{

rules:[

{

test:/\.js$/,

exclude:/node_modules/,

use:[

…………

]

},

{

test:/\.(png|jpg|gif)$/,

// 安装 url-loader file-loader

loader:'url-loader',

options:{

// 小于 8KB 转 base64

limit:8*1024

}

}

]

},

webpack5 :

  // 模块

module:{

rules:[

{

test:/\.js$/,

exclude:/node_modules/,

……………………

},

{

test:/\.(png|jpg|gif)$/,

// 通用资源类型

type:'asset',

// 现在,webpack 将按照默认条件,自动地在 resource 和 inline 之间进行选择:

// 小于 8kb 的文件,将会视为 inline 模块类型,否则会被视为 resource 模块类型。

// 自定义设置

parser:{

dataUrlCondition:{

maxSize:8*1024

}

}

}

]

},

文件缓存

https://webpack.docschina.org/configuration/other-options/#cache

缓存生成的 webpack 模块和 chunk,能够改善构建速度。

cache 会在 开发模式 下被设置成 type: 'memory' 而且在 生产模式 中被禁用。

cache: true 与 cache: { type: 'memory' } 配置作用一致。

cache.type

cache.type 将 cache 类型设置成内存或者文件系统。 'memory' | 'filesystem'

memory 选项很简单,它会告诉 webpack 将内容存放在内存中并且不允许额外的配置;

filesystem 选项,使用文件缓存系统;

cacheDirectory

cacheDirectory 定义缓存目录, 默认为 node_modules/.cache/webpack。

cache.cacheDirectory 选项仅当 cache.type 被设置成 filesystem 才可用。

webpack.config.js

  //  mode 工作模式

mode:'development',

cache:{

type:'filesystem',

// 默认缓存到 node_modules/.cache/webpack 中

// 也可以自定义缓存目录

// cacheDirectory:path.resolve(__dirname,'node_modules/.cac/webpack')

}

【JS】Webpack 5 新特性尝鲜

即使内容修改,增量编译的缓存效果也很明显

更好的 Tree Shaking

https://webpack.docschina.org/guides/tree-shaking/

Tree Shaking 技术,也被称为 “树摇” ,没错,翻译的就是这么直接,意思也很简单,未使用的导出内容不会被打包生成;它依赖于 ES2015 模块语法的 静态结构 特性,例如 import 和 export。这个术语和概念实际上是由 ES2015 模块打包工具 rollup 普及起来的。

为了更好说明这个原理,我做了一个动画,全网首发的动画效果,简单解释一下,有两个模块四个方法,在模块 x 中,使用了 B 方法和从模块Y中导入的 C 方法,而 X 模块中自己的 A 和模块 Y 中的 D 方法,并没有使用,虽然定义了,因为没有在任何地方使用过,因此,在 “摇树” 过程中,就会被 “摇掉”;

【JS】Webpack 5 新特性尝鲜

在 webpack 中如何使用呢?其实很简单,只要将 mode 工作模式改为 production 就会自动开启;
而如果想要感受这个树摇带来的震动酥麻酸爽的过程,我们也可以使用手动配置的方式来自行选择,首先需要将 mode 工作模式改为 none,意思就是不做任何优化,全部使用配置的方式,如何配置呢?添加 optimization.usedExports 和 optimization.minimize 选项,意思就是开启树摇及压缩

  //  mode 工作模式

mode: 'none', // production、development、none

// production 生产环境,默认优化打包

// none 不做任何操作

// usedExports:true 开启优化(树摇但保留代码)

// minimize:true 开启压缩 (删除未使用代码)

optimization:{

usedExports:true,

minimize:true

// innerGraph: true,

}

接下来,我们再使用简单代码做对比:
index.js

import * as m1 from "./m1";

console.log(m1.m2.nu1)

m1.js

import * as m2 from './m2'

export function fun1(){

console.log('1--11',m2.c);

}

export function fun2(){

console.log('1--22')

}

export {m2}

m2.js

export function fun3(){

console.log('2--33');

}

export function fun4(){

console.log('2--44')

}

export const nu1 = 456

export const nu2 = 789

【JS】Webpack 5 新特性尝鲜

相同的代码,在webpack 4 的打包结果中,我们能看到不仅代码量大,而且还有 i=789 这个多余的代码,反观 webpack 5 的打包结果,简洁到难以置信;

模块联邦

多个独立的构建可以组成一个应用程序,这些独立的构建之间不应该存在依赖关系,因此可以单独开发和部署它们。
这通常被称作微前端
为了更好地说明这个原理,我做了一个动画,全球首发的动画效果
【JS】Webpack 5 新特性尝鲜

【JS】Webpack 5 新特性尝鲜

导出模块

const path = require('path')

const HtmlWebpackPlugin = require('html-webpack-plugin')

// const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin")

const ModuleFederationPlugin = require("webpack").container.ModuleFederationPlugin;

…………

// 插件

plugins: [

new HtmlWebpackPlugin({

template: './src/index.html'

}),

new ModuleFederationPlugin({

// 模块名字

name: 'remote', //导入时使用名称标注

// 编译后的模块文件名,导入时使用

filename: 'remoteEntry.js',

// 导出模块 关键字与模块名

exposes: {

// "key导入时使用的关键字" : "对应模块文件"

"./Us": './src/User.js'

}

}),

],

导入模块

const path = require('path')

const HtmlWebpackPlugin = require('html-webpack-plugin')

const ModuleFederationPlugin = require("webpack").container.ModuleFederationPlugin;

…………

// 插件

plugins: [

new HtmlWebpackPlugin({

template: './src/index.html'

}),

new ModuleFederationPlugin({

name:'user:55',

// 导入外部模块

remotes:{

// 导入别名:关键字@地址/导出文件名

remoteHost:"[email protected]://127.0.0.1:3055/remoteEntry.js"

}

})

],

【JS】Webpack 5 新特性尝鲜

在 ModuleFederationPlugin 实例化的时候传入参数 options 的字段说明:

// 模块名字

name: 'remote', //导入时使用名称标注

// 编译后的模块文件名,导入时使用

filename: 'remoteEntry.js',

// 导出模块 关键字与模块名

exposes: {

// "key导入时使用的关键字" : "对应模块文件"

"./Us": './src/User.js'

}

// 导入外部模块

remotes:{

// 导入别名:关键字@地址/导出文件名

remoteHost:"[email protected]://127.0.0.1:3055/remoteEntry.js"

}

还有就是 exposes 和 remotes 的字段小伙伴们也要注意,

  • exposes 的暴露字段要写上 ./name
  • remotes 的字段跟暴露模块的 name 保持一致,里面别名的定义也要一致

最后,两个应用同时启动,就会发现最终你要的应用就把其他应用的模块也引入进来了

javascript前端webpack

阅读 46发布于 今天 03:37

本作品系原创,采用《署名-非商业性使用-禁止演绎 4.0 国际》许可协议

avatar

西岭老湿

0 声望

0 粉丝

0 条评论

得票时间

avatar

西岭老湿

0 声望

0 粉丝

宣传栏

安装与启动

Webpack 5 发布已经有一段时间了,很多小伙伴都在考虑要不要升级,有没有升级的必要,不知道升级后有哪些改变;
今天我们就来做个对比看看,webpack5 带来了那些全新的改变;
没有对比就没有伤害,为了更好地伤害 webpack 4 , 我们使用 webpack4 和 webpack 5 分别构建一个 React 项目来做对比:

mkdir webpack4

mkdir webpack5

# 分别执行 初始化命令

npm init -y

创建文件 /src/index.js, /src/App.js, /src/index.html

React 代码示例
index.js

import React from "react"

import ReactDom from "react-dom"

import App from "./App"

ReactDom.render(,document.getElementById('root'))

App.js
【JS】Webpack 5 新特性尝鲜

index.html

<!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>

<!-- 加一行注释 -->

<div id="root"></div>

</body>

</html>

安装与启动

webpack4

// webpack4

npm install [email protected] [email protected] html-webpack-plugin css-loader style-loader babel-loader @babel/core @babel/preset-env @babel/preset-react -D

npm install react react-dom

因为仓库中目前默认就已经是 webpack5 了,所以,想要安装 webpack4, 我们需要加上 @4 的版本号;

webpack5

// webpack5

npm install webpack webpack-cli html-webpack-plugin css-loader style-loader babel-loader @babel/core @babel/preset-env @babel/preset-react -D

npm install react react-dom

基础配置 webpack.config.js

const path = require('path')

const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {

// entry 入口,output出口,module模块,plugins 插件 mode工作模式,devServer开发服务器

// mode 工作模式

mode: 'development', // production 、 development、none

// 入口

entry:'./src/index.js',

// 出口

output:{

filename:'./bundle.js',

path:path.resolve(__dirname,'dist')

},

// 模块

module:{

rules:[

{

test:/\.js$/,

exclude:/node_modules/,

use:[

{

loader:'babel-loader',

options:{

presets:[

'@babel/preset-env',

'@babel/preset-react'

]

}

}

]

},

]

},

// 插件

plugins:[

new HtmlWebpackPlugin({

template:'./src/index.html'

})

]

}

启动命令的区别
先安装 npm install webpack-dev-server -D
配置服务器:

  //  服务器

devServer:{

port:3004,

open:true

},

webpack 4 : webpack4/package.json

"scripts": {

"test": "echo \"Error: no test specified\" && exit 1",

"build": "webpack",

"start": "webpack-dev-server"

},

webpack 5 : webpack5/package.json

 "scripts": {

"test": "echo \"Error: no test specified\" && exit 1",

"build":"webpack",

"start":"webpack serve"

},

资源模块处理

https://webpack.docschina.org/guides/asset-modules/#source-assets

资源模块(asset module)是一种模块类型,它允许使用资源文件(字体,图标等)而无需配置额外 loader。

在 webpack 5 之前,通常使用:

  • raw-loader 将文件导入为字符串

  • url-loader 将文件作为 data URI 内联到 bundle 中

  • file-loader 将文件发送到输出目录

资源模块类型(asset module type),通过添加 4 种新的模块类型,来替换所有这些 loader:

  • asset/resource 发送一个单独的文件并导出 URL(之前通过使用 file-loader 实现)
  • asset/inline 导出一个资源的 data UR(之前通过使用 url-loader 实现)
  • asset/source 导出资源的源代码(之前通过使用 raw-loader 实现)
  • asset 在导出一个 data URI 和发送一个单独的文件之间自动选择(之前通过使用 url-loader,并且配置资源体积限制实现)

webpack4 :

  // 模块

module:{

rules:[

{

test:/\.js$/,

exclude:/node_modules/,

use:[

…………

]

},

{

test:/\.(png|jpg|gif)$/,

// 安装 url-loader file-loader

loader:'url-loader',

options:{

// 小于 8KB 转 base64

limit:8*1024

}

}

]

},

webpack5 :

  // 模块

module:{

rules:[

{

test:/\.js$/,

exclude:/node_modules/,

……………………

},

{

test:/\.(png|jpg|gif)$/,

// 通用资源类型

type:'asset',

// 现在,webpack 将按照默认条件,自动地在 resource 和 inline 之间进行选择:

// 小于 8kb 的文件,将会视为 inline 模块类型,否则会被视为 resource 模块类型。

// 自定义设置

parser:{

dataUrlCondition:{

maxSize:8*1024

}

}

}

]

},

文件缓存

https://webpack.docschina.org/configuration/other-options/#cache

缓存生成的 webpack 模块和 chunk,能够改善构建速度。

cache 会在 开发模式 下被设置成 type: 'memory' 而且在 生产模式 中被禁用。

cache: true 与 cache: { type: 'memory' } 配置作用一致。

cache.type

cache.type 将 cache 类型设置成内存或者文件系统。 'memory' | 'filesystem'

memory 选项很简单,它会告诉 webpack 将内容存放在内存中并且不允许额外的配置;

filesystem 选项,使用文件缓存系统;

cacheDirectory

cacheDirectory 定义缓存目录, 默认为 node_modules/.cache/webpack。

cache.cacheDirectory 选项仅当 cache.type 被设置成 filesystem 才可用。

webpack.config.js

  //  mode 工作模式

mode:'development',

cache:{

type:'filesystem',

// 默认缓存到 node_modules/.cache/webpack 中

// 也可以自定义缓存目录

// cacheDirectory:path.resolve(__dirname,'node_modules/.cac/webpack')

}

【JS】Webpack 5 新特性尝鲜

即使内容修改,增量编译的缓存效果也很明显

更好的 Tree Shaking

https://webpack.docschina.org/guides/tree-shaking/

Tree Shaking 技术,也被称为 “树摇” ,没错,翻译的就是这么直接,意思也很简单,未使用的导出内容不会被打包生成;它依赖于 ES2015 模块语法的 静态结构 特性,例如 import 和 export。这个术语和概念实际上是由 ES2015 模块打包工具 rollup 普及起来的。

为了更好说明这个原理,我做了一个动画,全网首发的动画效果,简单解释一下,有两个模块四个方法,在模块 x 中,使用了 B 方法和从模块Y中导入的 C 方法,而 X 模块中自己的 A 和模块 Y 中的 D 方法,并没有使用,虽然定义了,因为没有在任何地方使用过,因此,在 “摇树” 过程中,就会被 “摇掉”;

【JS】Webpack 5 新特性尝鲜

在 webpack 中如何使用呢?其实很简单,只要将 mode 工作模式改为 production 就会自动开启;
而如果想要感受这个树摇带来的震动酥麻酸爽的过程,我们也可以使用手动配置的方式来自行选择,首先需要将 mode 工作模式改为 none,意思就是不做任何优化,全部使用配置的方式,如何配置呢?添加 optimization.usedExports 和 optimization.minimize 选项,意思就是开启树摇及压缩

  //  mode 工作模式

mode: 'none', // production、development、none

// production 生产环境,默认优化打包

// none 不做任何操作

// usedExports:true 开启优化(树摇但保留代码)

// minimize:true 开启压缩 (删除未使用代码)

optimization:{

usedExports:true,

minimize:true

// innerGraph: true,

}

接下来,我们再使用简单代码做对比:
index.js

import * as m1 from "./m1";

console.log(m1.m2.nu1)

m1.js

import * as m2 from './m2'

export function fun1(){

console.log('1--11',m2.c);

}

export function fun2(){

console.log('1--22')

}

export {m2}

m2.js

export function fun3(){

console.log('2--33');

}

export function fun4(){

console.log('2--44')

}

export const nu1 = 456

export const nu2 = 789

【JS】Webpack 5 新特性尝鲜

相同的代码,在webpack 4 的打包结果中,我们能看到不仅代码量大,而且还有 i=789 这个多余的代码,反观 webpack 5 的打包结果,简洁到难以置信;

模块联邦

多个独立的构建可以组成一个应用程序,这些独立的构建之间不应该存在依赖关系,因此可以单独开发和部署它们。
这通常被称作微前端
为了更好地说明这个原理,我做了一个动画,全球首发的动画效果
【JS】Webpack 5 新特性尝鲜

【JS】Webpack 5 新特性尝鲜

导出模块

const path = require('path')

const HtmlWebpackPlugin = require('html-webpack-plugin')

// const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin")

const ModuleFederationPlugin = require("webpack").container.ModuleFederationPlugin;

…………

// 插件

plugins: [

new HtmlWebpackPlugin({

template: './src/index.html'

}),

new ModuleFederationPlugin({

// 模块名字

name: 'remote', //导入时使用名称标注

// 编译后的模块文件名,导入时使用

filename: 'remoteEntry.js',

// 导出模块 关键字与模块名

exposes: {

// "key导入时使用的关键字" : "对应模块文件"

"./Us": './src/User.js'

}

}),

],

导入模块

const path = require('path')

const HtmlWebpackPlugin = require('html-webpack-plugin')

const ModuleFederationPlugin = require("webpack").container.ModuleFederationPlugin;

…………

// 插件

plugins: [

new HtmlWebpackPlugin({

template: './src/index.html'

}),

new ModuleFederationPlugin({

name:'user:55',

// 导入外部模块

remotes:{

// 导入别名:关键字@地址/导出文件名

remoteHost:"[email protected]://127.0.0.1:3055/remoteEntry.js"

}

})

],

【JS】Webpack 5 新特性尝鲜

在 ModuleFederationPlugin 实例化的时候传入参数 options 的字段说明:

// 模块名字

name: 'remote', //导入时使用名称标注

// 编译后的模块文件名,导入时使用

filename: 'remoteEntry.js',

// 导出模块 关键字与模块名

exposes: {

// "key导入时使用的关键字" : "对应模块文件"

"./Us": './src/User.js'

}

// 导入外部模块

remotes:{

// 导入别名:关键字@地址/导出文件名

remoteHost:"[email protected]://127.0.0.1:3055/remoteEntry.js"

}

还有就是 exposes 和 remotes 的字段小伙伴们也要注意,

  • exposes 的暴露字段要写上 ./name
  • remotes 的字段跟暴露模块的 name 保持一致,里面别名的定义也要一致

最后,两个应用同时启动,就会发现最终你要的应用就把其他应用的模块也引入进来了

以上是 【JS】Webpack 5 新特性尝鲜 的全部内容, 来源链接: utcz.com/a/112911.html

回到顶部