分离方法

image.png
第一种:多个入口时,多入口的共享文件会分别在每一个包中重复打包
第二种:防止了第一种打包时会重复打包的问题
第三种:动态导入,通过模块的内联函数import

入口起点

image.png

  1. const path = require("path")
  2. const HtmlWebpackPlugin = require("html-webpack-plugin")
  3. module.export = {
  4. // 配置多入口
  5. entry:{
  6. index:"./src/index.js",
  7. another:"./src/another-module.js"
  8. },
  9. output:{
  10. // [name]会获取到entry中的key值,(这是多入口时必须要的,否则会提示这两个文件会被打包成一个文件名,进而引起冲突)
  11. // 这将会有利于生成不同的打包后文件名
  12. filename:"[name].bundle.js",
  13. path:path.resolve(__dirname,"./dist"),
  14. clean:true,
  15. assetModuleFilename:"images/[contenthash][ext]"
  16. },
  17. // mode:"development",
  18. // devtool:"inline-source-map",
  19. // plugins: [
  20. // new HtmlWebpackPlugin({
  21. // template:"./index.html",
  22. // filename:"app.html",
  23. // inject:"body"
  24. // })
  25. // ],
  26. // 定义哪些资源文件需要打包
  27. module:{
  28. rules:[
  29. // {
  30. // test:/\.png$/,
  31. // type:"asset/resource",
  32. // generator:{
  33. // filename:"images/[contenthash][ext]"
  34. // }
  35. // },
  36. // {
  37. // test:/\.svg$/,
  38. // type:"asset/inline",
  39. // },
  40. // {
  41. // test:/\.txt$/,
  42. // type:"asset/source",
  43. // },
  44. // {
  45. // test:/\.jpg$/,
  46. // type:"asset",
  47. // // 解析器
  48. // parser:{
  49. // // 定义是否生成URL的临界值,当文件大于时创建,反之生成URL
  50. // dataUrlCondition:{
  51. // maxSize:4*1024*1024
  52. // }
  53. // }
  54. // }
  55. // {
  56. // test:/\.css$/,
  57. // use:["style-loader","css-loader"]
  58. // }
  59. ]
  60. }
  61. }

通过这种方式打包时会将入口文件中引入的库页一并进行打包。并且在打包过程中即使两个入口文件都引入了同一个库,但是在打包时会各自的打包各自的引入文件(会多次打包同一个文件),而不是相同的库被提取出来打包成一份

防止重复

image.png

  1. const path = require("path")
  2. const HtmlWebpackPlugin = require("html-webpack-plugin")
  3. module.export = {
  4. // 配置多入口
  5. entry:{
  6. // 设置入口文件
  7. index:{
  8. import:"./src/index.js",
  9. // 设置文件是否可以共享
  10. dependOn:"shared"
  11. },
  12. another:{
  13. import:"./src/another-module.js",
  14. dependOn:"shared"
  15. },
  16. // 提取公共文件,并取名为shared
  17. // 同上面两个入口文件中都有loadsh模块时,将loadsh提取出来并重命名为shared
  18. shared:'loadsh'
  19. },
  20. output:{
  21. // [name]会获取到entry中的key值,(这是多入口时必须要的,否则会提示这两个文件会被打包成一个文件名,进而引起冲突)
  22. // 这将会有利于生成不同的打包后文件名
  23. filename:"[name].bundle.js",
  24. path:path.resolve(__dirname,"./dist"),
  25. clean:true,
  26. assetModuleFilename:"images/[contenthash][ext]"
  27. },
  28. // mode:"development",
  29. // devtool:"inline-source-map",
  30. // plugins: [
  31. // new HtmlWebpackPlugin({
  32. // template:"./index.html",
  33. // filename:"app.html",
  34. // inject:"body"
  35. // })
  36. // ],
  37. // 定义哪些资源文件需要打包
  38. module:{
  39. rules:[
  40. // ...
  41. ]
  42. }
  43. }

打包:(将shared单独抽离)
image.pngimage.png

在webpack中使用插件实现上面的过程

  1. const path = require("path")
  2. const HtmlWebpackPlugin = require("html-webpack-plugin")
  3. module.export = {
  4. // 配置多入口
  5. entry:{
  6. index:"./src/index.js",
  7. another:"./src/another-module.js"
  8. },
  9. output:{
  10. // [name]会获取到entry中的key值,(这是多入口时必须要的,否则会提示这两个文件会被打包成一个文件名,进而引起冲突)
  11. // 这将会有利于生成不同的打包后文件名
  12. filename:"[name].bundle.js",
  13. path:path.resolve(__dirname,"./dist"),
  14. clean:true,
  15. assetModuleFilename:"images/[contenthash][ext]"
  16. },
  17. // mode:"development",
  18. // devtool:"inline-source-map",
  19. // plugins: [
  20. // new HtmlWebpackPlugin({
  21. // template:"./index.html",
  22. // filename:"app.html",
  23. // inject:"body"
  24. // })
  25. // ],
  26. // 定义哪些资源文件需要打包
  27. module:{
  28. rules:[
  29. // ...
  30. ]
  31. },
  32. // 优化插件
  33. optimization:{
  34. // 压缩代码
  35. minimizer:{
  36. new CssMinimizerPlugin()
  37. },
  38. // 分离代码
  39. // 配置后,将会自动把公共的代码抽离到单独的文件中
  40. splitChunks:{
  41. chunks:"all"
  42. }
  43. }
  44. }

动态导入

通过import函数动态的导入需要的模块,impoort返回一个promise对像。
通过import函数动态导入的模块最后会被抽离出来单独打包
在src文件的根目录创建一个async-module.js文件

  1. function getCompnent() {
  2. // 通过import来处理loadsh这一文件
  3. // import 会返回一个promise对象
  4. return import("loadsh")
  5. .then(({default:_})=> {
  6. const element = document.createElement("div")
  7. element.innerHTML = _.join(["HEllo","webpack"]," ")
  8. return element
  9. })
  10. }
  11. getComponent().then((element) => {
  12. document.body.appendChild(element)
  13. })

在入口文件中引入这个文件
这时打包就会将loadsh抽离了单独打包。

  1. const path = require("path")
  2. const HtmlWebpackPlugin = require("html-webpack-plugin")
  3. module.export = {
  4. // 配置多入口
  5. entry:{
  6. index:"./src/index.js",
  7. another:"./src/another-module.js"
  8. },
  9. output:{
  10. // [name]会获取到entry中的key值,(这是多入口时必须要的,否则会提示这两个文件会被打包成一个文件名,进而引起冲突)
  11. // 这将会有利于生成不同的打包后文件名
  12. filename:"[name].bundle.js",
  13. path:path.resolve(__dirname,"./dist"),
  14. clean:true,
  15. assetModuleFilename:"images/[contenthash][ext]"
  16. },
  17. // mode:"development",
  18. // devtool:"inline-source-map",
  19. // plugins: [
  20. // new HtmlWebpackPlugin({
  21. // template:"./index.html",
  22. // filename:"app.html",
  23. // inject:"body"
  24. // })
  25. // ],
  26. // 定义哪些资源文件需要打包
  27. module:{
  28. rules:[
  29. // ...
  30. ]
  31. },
  32. // 优化插件
  33. optimization:{
  34. // 压缩代码
  35. minimizer:{
  36. new CssMinimizerPlugin()
  37. },
  38. // 分离代码
  39. // 配置后,将会自动把公共的代码抽离到单独的文件中
  40. // splitChunks:{
  41. // chunks:"all"
  42. // }
  43. }
  44. }

当动态导入和静态导入一起使用时,需要使用代码分离的优化配置:如下
image.png

懒加载

懒加载是动态导入的一个应用
image.png
image.png

重命名动态导入文件的打包文件名

通过 / webpackChunkName: ‘math’ / 可以将打包文件重命名

  1. import(/* webpackChunkName: 'math' */./math.js).then(...)

预获取/预加载模块

image.png

  1. import(/* webpackChunkName: 'math',webpackPrefetch:true */./math.js).then(...)

在加载math.js的打包文件(math.boundle.js)时,这一加载过程会被放到最后(浏览器空闲的时候),当其他非预加载文件加载完成后,才会加载这个文件(将将来需要的模块先加载下来)。
webpackPrefetch 这个属性会让文件在页面初始化时就被加载,但一般都是放在浏览器空闲时加载。
效果:导入时加上了rel=”prefetch”属性
image.png

  1. import(/* webpackChunkName: 'math',webpackPreload:true */./math.js).then(...)

webpackPreload这个属性不用于实现模块的并行加载(与懒加载有点相似)