webpack系列--浅析webpack的原理 (2)

一个项目中会包含多个单页应用,虽然多个单页面应用可以合成一个,但是这样做会导致用户没有访问的部分也加载了,如果项目中有很多的单页应用。为每一个单页应用配置一个entry和WebPlugin?如果又新增,又要新增webpack配置,这样做麻烦,这时候有一个插件web-webpack-plugin里的AutoWebPlugin方法可以解决这些问题。

module.exports = { plugins: [ // 所有页面的入口目录 new AutoWebPlugin('./src/'), ] };

分析:1、AutoWebPlugin会把./src/目录下所有每个文件夹作为一个单页页面的入口,自动为所有的页面入口配置一个WebPlugin输出对应的html。

2、要新增一个页面就在./src/下新建一个文件夹包含这个单页应用所依赖的代码,AutoWebPlugin自动生成一个名叫文件夹名称的html文件。

 

3、代码分隔优化

一个好的代码分割对浏览器首屏效果提升很大。

最常见的react体系:

(1)先抽出基础库react react-dom redux react-redux到一个单独的文件而不是和其它文件放在一起打包为一个文件,这样做的好处是只要你不升级他们的版本这个文件永远不会被刷新。如果你把这些基础库和业务代码打包在一个文件里每次改动业务代码都会导致文件hash值变化从而导致缓存失效浏览器重复下载这些包含基础库的代码。所以把基础库打包成一个文件

// vender.js 文件抽离基础库到单独的一个文件里防止跟随业务代码被刷新 // 所有页面都依赖的第三方库 // react基础 import 'react'; import 'react-dom'; import 'react-redux'; // redux基础 import 'redux'; import 'redux-thunk'; // webpack配置 { entry: { vendor: './path/to/vendor.js', }, }

(2)通过可以提取出多个代码块都依赖的代码形成一个单独的chunk。在应用有多个页面的场景下提取出所有页面公共的代码减少单个页面的代码,在不同页面之间切换时所有页面公共的代码之前被加载过而不必重新加载。所以通过可以提取出多个代码块都依赖的代码形成一个单独的chunk。

 

4、构建服务端渲染

服务端渲染的代码要运行在nodejs环境,和浏览器不同的是,服务端渲染代码需要采用commonjs规范同时不应该包含除js之外的文件比如css。

webpack配置如下:

module.exports = { target: 'node', entry: { 'server_render': './src/server_render', }, output: { filename: './dist/server/[name].js', libraryTarget: 'commonjs2', }, module: { rules: [ { test: /\.js$/, loader: 'babel-loader', }, { test: /\.(scss|css|pdf)$/, loader: 'ignore-loader', }, ] }, };

分析一下:

(1)target: 'node'指明构建出代码要运行在node环境中。

(2)libraryTarget: 'commonjs2' 指明输出的代码要是commonjs规范。

(3){test: /\.(scss|css|pdf)$/,loader: 'ignore-loader'} 是为了防止不能在node里执行服务端渲染也用不上的文件被打包进去。

 

5、fis3迁移到webpack

fis3和webpack有很多相似地方也有不同的地方,相似地方:都采用commonjs规范,不同地方:导入css这些非js资源的方式。

fis3通过@require './index.scss',而webpack是通过require('./index.scss')。

如果想把fis3平滑迁移到webpack,可以使用comment-require-loader。

比如:你想在webpack构建是使用采用了fis3方式的imui模块

loaders:[{ test: /\.js$/, loaders: ['comment-require-loader'], include: [path.resolve(__dirname, 'node_modules/imui'),] }]

 

四、自定义webpack扩展

如果你在社区找不到你的应用场景的解决方案,那就需要自己动手了写loader或者plugin了。
在你编写自定义webpack扩展前你需要想明白到底是要做一个loader还是plugin呢?可以这样判断:

如果你的扩展是想对一个个单独的文件进行转换那么就编写loader剩下的都是plugin。

其中对文件进行转换可以是像:

1、babel-loader把es6转为es5;

2、file-loader把文件替换成对应的url;

3、raw-loader注入文本文件内容到代码中。

1、编写webpack loader

编写loader非常简单,以comment-require-loader为例:

module.exports = function (content) { return replace(content); };

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpyxzp.html