webpack5

2020-12-27  本文已影响0人  我是小布丁

1、不再为Node.js模块自动引入Polyfills

在 Webpack 4 或之前的版本中,任何项目引用 Node.js 内置模块都会自动添加 Polyfills,Polyfills是一个语法检查的模版工具。不过,Webpack 5不再为 Node.js 内置模块自动添加 Polyfills,Webpack 5会投入更多的精力到前端模块的兼容性工作中

如果你的代码中有引用这些 Node.js 的模块,当需要升级到 Webpack 5版本时, 请将尽量使用前端的模块,或者自行手动添加适合的 Polyfills。

module.exports = {
    resolve:{
        /* fallback:{
            'crypto':require.resolve('crypto-browserify'),
            'stream':require.resolve('stream-browserify'),
            'buffer':require.resolve('buffer')
        }, */
        fallback:{
            'crypto':false,
            'stream':false,
            'buffer':false
        }
    },
}

2、moduleId和ChunkId优化

Webpack 5新增了长期缓存的算法,这些算法在生产模式下是默认启用的,语法格式如下。

module.exports = {
  optimization: {
    moduleIds: 'deterministic'   //natural  named size
   chunkIds: 'deterministic'  //natural  named size total-size,开发默认named,生产默认deterministic
  }
};

该算法以确定性的方式为模块和分块分配短的(3 位)数字 ID,这是包大小和长期缓存之间的一种权衡。由于这些配置将使用确定的 ID 和名称,这意味着生成的缓存失效不再更频繁。

3、资源模块

Webpack 5 现在已经对表示资源的模块提供了内置支持。这些模块可以向输出文件夹发送一个文件,或者向 Javascript 包注入一个 DataURI。 无论哪种方式,它们都会给出一个 URL 来让程序正常工作。不需要单独安装raw-loader、url-loader、file-loader

module.exports = {
  module:{
        rules:[
              {
                test:/\.png$/,
                type: 'asset/resource'   //对标file-loader
            },
            {
                test:/\.ico$/,
                type: 'asset/inline'   //对标url-loader 模块的大小<limit base64字符串
            },
            {
                test:/\.txt$/,
                type:'asset/source'   //对标raw-loader
            },
            {
                test:/\.jpg$/,
                type:'asset',   //对标raw-loader
                parser:{
                    dataUrlCondition:{
                        maxSize: 4*1024
                    }
                }
            },
       ]
}

参考官方地址

4、性能优化

持久化缓存

module.exports = {
    cache:{
        //不要再使用cnpm来安装模块
        type: 'filesystem',  //memory filesystem
        cacheDirectory: path.resolve(__dirname, 'node_modules/.cache/webpack'), //filesystem时自定义缓存路径
    }
}

参考官方地址

5、构建优化

tree-shaking

Webpack5能够跟踪对导出的嵌套属性的访问,因此可以改善重新导出命名空间对象时的 Tree Shaking(清除未使用的导出和混淆导出)。
Webpack 5 有一个新的选项 optimization.innerGraph,在生产模式下是默认启用的,它可以对模块中的标志进行分析,找出导出和引用之间的依赖关系。
要获得未使用的导出信息,需要使用 optimization.usedExports。要删除无副作用的模块,需要使用optimization.sideEffects

module.exports = {
  optimization:{
        usedExports: true,  //标使用到的导出
    }
}

package.json配置

"sideEffects": [
    "*.css",
    "@babel/polyfill"
  ],

参考官方地址

6、模块联邦 module federation

从开发者的角度来看,模块可以从指定的远程构建中导入,并以最小的限制来使用

remote端

const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');
module.exports = {
plugins: [
       ...
        new ModuleFederationPlugin({
            name:  'remoteVar',// remote向外暴露的全局变量名
            filename: 'remoteEntry.js',//构建出来的文件名
            exposes:{
                './NewsList': './src/NewsList'
            },
            shared:['react',   'react-dom']    
        })
    ]
}

host端

const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');
module.exports = {
   plugins: [
        ...
        new ModuleFederationPlugin({
            remotes:{
                remote: 'remoteVar@http://localhost:8080/remoteEntry.js'
            },
            shared:['react','react-dom']    
        })
    ]
}
const RemoteNewList = React.lazy(()=>import('remote/NewsList'));
const App = ()=>(
    <div>
        <React.Suspense fallback="Loading NewsList">
            <RemoteNewList/>
        </React.Suspense>
    </div>
)

因此可以使用 [name]/[exposes_name] 这个模块,这个模块对于被引用应用来说是一个本地模块
通过 shared 选项 —— remotes 将会首先依赖来自 host 的依赖,如果 host 没有依赖,它将会下载自己的依赖。没有代码层面的冗余,而只有内置的冗余
Webpack 5 Module Federation: JavaScript 架构的变革者

参考文章

Webpack 5 新特性

上一篇 下一篇

猜你喜欢

热点阅读