webpaack代码分割 + 懒加载demo练习, webpack3.10.0版本搭建,目前webpack4.X版本不兼容。
实现懒加载两种方式,一种webpack内置方法,一种es 2015 loader
1.webapck method
1)require.ensure()
接受四个参数: []: dependencies
callback
errorCallBack(该参数可省略)
chunkName
注: require.ensure需依赖promise方法,如果不支持,需添加polyfill进行语法转义
2)require.include
当子模块中都依赖第三方模块时,可将第三方模块在父模块通过该方法打包
2.ES 2015 Loader spec
import() -> Promise // 通过import方式调用,返会promise对象
import().then() // 相当于该方式使用
代码分割场景:
1.分离业务代码 和 第三方依赖
2.分离业务代码 和 业务公共代码 和 第三方依赖
3.分离首次加载 和 访问后加载的代码(用于前端优化)
demo练习
1)代码结构如下:
2)各部分代码:
moduleA.js:
// 只导出该文件,作为公共代码依赖,用于代码练习 export default 'moduleA';
pageA.js
// import './subPageA'; // 同步加载 // import './subPageB' // 同步加载方式 // import * as _ from 'lodash'; //************以上为webpack3.5练习代码 */ // 通过require.include()方法将,子模块中公共moduleA提取出来 require.include('./moduleA'); // 采用import方式动态引入 /** * import(依赖).then(); * 在依赖中通过加注释: webpackChunkName: ‘name'方式 给定chunk name * 如果多个import指定的chunk name相同,则会将不同的依赖都打入到同一个chunk 中 */ import(/* webpackChunkName: 'subPageA' */'./subPageA').then(function(pageA) { console.log(pageA) }) // 懒加载方式1, 采用require.ensure方式加载subPageA/subPageB/lodash /** * require,ensure方法四个参数: * 【】 依赖 * callback * errorCallBack(该参数可省略), * chunkname */ // require.ensure('./subPageA', function() { // var subPageA = require('./subPageA'); // require之后代码才会真正执行 // }, 'subPageA'); require.ensure('./subPageB', function() { // var subPageB = require('./subPageB'); // 如果没有require 则代码不会执行 }, 'subPageB'); require.ensure([], function(){ var _ = require('lodash'); // require之后才会真正的执行 _.join(['1', '2'], '3'); }, 'vendor') export default 'PageA';
pageB.js
// export default import './subPageA'; import './subPageB'; import * as _ from 'lodash'; export default 'PageB';
subPageA.js
import './moduleA'; console.log('tgis is subpageA'); export default 'subPageA';
subPageB.js
import './moduleA'; console.log('this.is subPageB'); export default 'subPageB';
webpack.config.jvar webpack = require('webpack');var path = require('path');
module.exports = { entry: { 'pageA': './src/pageA', // 由于是单entry,则commonschunkplugin不会起作用 // 采用require.include方式进行代码分割 // 'pageB': './src/pageB', // 'vendor': ['lodash'] // 指定第三方插件单独打包 }, output: { path: path.resolve(__dirname, './dist'), // The publicPath configuration option can be quite useful in a variety of scenarios. // It allows you to specify the base path for all the assets within your application. publicPath: './dist/', // 代码动态加载地址 filename: '[name].bundle.js', chunkFilename: '[name].chunk.js' }, module: { rules: [ ] }, // plugins: [ // // 将业务代码中公共出现的部分进行抽取 // new webpack.optimize.CommonsChunkPlugin({ // name: 'common', // minChunks: 2, // chunks: ['pageA', 'pageB'] // }),
// new webpack.optimize.CommonsChunkPlugin({ // // names: ['vendor', 'mainfest'] // 可使用names参数,将vendor与manifest合并配置 // name: 'vendor', // 指定从vender中抽取公共代码 // minChunks: Infinity // 不需要重复 // // name: 'common', // 公共代码名称为common // // minChunks: 2 // 在所有的chunk中出现2次就打包 // }), // // 想将webpack代码独立出来,保持第三方代码纯净,可以在补充一个commonchunkpluginspeizhi // new webpack.optimize.CommonsChunkPlugin({ // name: 'mainfest', // minChunks: Infinity // }) // ] }
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <!- 引入打包后的pageA.bundle.js 查看其他代码是否能够加载--> <script src='./dist/pageA.bundle.js'></script> </head> <body> </body> </html>