方案一

  1. webpack-demo
  2. |- package.json
  3. |- webpack.common.js
  4. |- webpack.dev.js
  5. |- webpack.prod.js
  6. |- server.js
  7. |- DEV-server.js
  8. |- /dist
  9. |- /src
  10. |- data.xml
  11. |- icon.png+
  12. |- style.css
  13. |- my-font.woff
  14. |- my-font.woff2
  15. |- print.js
  16. |- index.js
  17. |- math.js
  18. |- /node_modules
  1. // index.js
  2. import _ from 'lodash';
  3. import './style.css';
  4. import Icon from './icon.svg';
  5. import Data from './data.xml';
  6. import printMe from './print.js';
  7. import { cube } from './math.js';
  8. function componentPre() {
  9. let element = document.createElement('pre');
  10. element.innerHTML = [
  11. 'Hello webpack!',
  12. '5 cubed is equal to ' + cube(5)
  13. ].join('\n\n');
  14. element.classList.add('hello');
  15. var myIcon = new Image();
  16. myIcon.src = Icon;
  17. element.appendChild(myIcon);
  18. var btn = document.createElement('button');
  19. btn.innerHTML = 'Click me and check the console!';
  20. btn.onclick = printMe;
  21. element.appendChild(btn);
  22. console.log(Data);
  23. return element;
  24. }
  25. function component() {
  26. let element = document.createElement('div');
  27. element.innerHTML = _.join(['Hello', 'webpack'], ' ');
  28. element.classList.add('hello');
  29. var myIcon = new Image();
  30. myIcon.src = Icon;
  31. element.appendChild(myIcon);
  32. var btn = document.createElement('button');
  33. btn.innerHTML = 'Click me and check the console!';
  34. btn.onclick = printMe;
  35. element.appendChild(btn);
  36. console.log(Data);
  37. return element;
  38. }
  39. // document.body.appendChild(component());
  40. let element = componentPre(); // Store the element to re-render on print.js changes
  41. document.body.appendChild(element);
  42. if (module.hot) {
  43. module.hot.accept('./print.js', function () {
  44. console.log('Accepting the updated printMe module!');
  45. document.body.removeChild(element);
  46. element = componentPre(); // Re-render the "component" to update the click handler
  47. document.body.appendChild(element);
  48. })
  49. }
  1. // print.js
  2. import _ from 'lodash';
  3. export default function printMe() {
  4. // console.log('I get called from print.js!');
  5. console.log('Updating print.js...' + _.join(['Another', 'module', 'loaded!'], ' '));
  6. }
  1. // webpack.common.js
  2. const path = require('path');
  3. const HtmlWebpackPlugin = require('html-webpack-plugin'); // 自动生成页面
  4. const CleanWebpackPlugin = require('clean-webpack-plugin'); // 自动清理,清理dist旧文件
  5. const webpack = require('webpack');
  6. module.exports = {
  7. entry: {
  8. app: './src/index.js',
  9. print: './src/print.js',
  10. },
  11. optimization: { // 防止重复
  12. splitChunks: {
  13. chunks: 'all'
  14. }
  15. },
  16. plugins: [
  17. new CleanWebpackPlugin(['dist']),
  18. new HtmlWebpackPlugin({
  19. title: 'Output Management'
  20. }),
  21. new webpack.HotModuleReplacementPlugin()
  22. ],
  23. output: {
  24. filename: '[name].bundle.js',
  25. path: path.resolve(__dirname, 'dist'),
  26. publicPath: '/'
  27. },
  28. module: {
  29. rules: [
  30. {
  31. test: /\.css$/,
  32. use: [
  33. 'style-loader',
  34. 'css-loader'
  35. ]
  36. },
  37. {
  38. test: /\.(png|svg|jpg|gif)$/,
  39. use: [
  40. 'file-loader'
  41. ]
  42. },
  43. {
  44. test: /\.(woff|woff2|eot|ttf|otf)$/,
  45. use: [
  46. 'file-loader'
  47. ]
  48. },
  49. {
  50. test: /\.(csv|tsv)$/,
  51. use: [
  52. 'csv-loader'
  53. ]
  54. },
  55. {
  56. test: /\.xml$/,
  57. use: [
  58. 'xml-loader'
  59. ]
  60. }
  61. ],
  62. }
  63. };

有了optimization.splitChunks配置选项,我们现在应该看到从我们的index.bundle.js和中删除了重复的依赖项print.bundle.js。该插件应该注意到我们已经分离lodash出一个单独的块并从我们的主捆绑中移除了自重

以下是社区提供的用于拆分代码的一些其他有用的插件和加载器:

方案二

在动态代码拆分方面,webpack支持两种类似的技术。第一种建议的方法是使用符合ECMAScript提议import()语法进行动态导入。传统的,特定于webpack的方法是使用。让我们尝试使用这两种方法中的第一种……

import()调用内部使用promises。如果您使用import()较旧的浏览器,请记住使用填充程序来填充,Promise例如es6-promisepromise- polyfill

  1. // webpack.common.js
  2. const path = require('path');
  3. const HtmlWebpackPlugin = require('html-webpack-plugin'); // 自动生成页面
  4. const CleanWebpackPlugin = require('clean-webpack-plugin'); // 自动清理,清理dist旧文件
  5. const webpack = require('webpack');
  6. module.exports = {
  7. entry: {
  8. app: './src/index.js',
  9. // print: './src/print.js',
  10. },
  11. // optimization: { // 防止重复
  12. // splitChunks: {
  13. // chunks: 'all'
  14. // }
  15. // },
  16. plugins: [
  17. new CleanWebpackPlugin(['dist']),
  18. new HtmlWebpackPlugin({
  19. title: 'Output Management'
  20. }),
  21. new webpack.HotModuleReplacementPlugin()
  22. ],
  23. output: {
  24. filename: '[name].bundle.js',
  25. // ==================================================================
  26. chunkFilename: '[name].bundle.js', // 使用这个
  27. // ==================================================================
  28. path: path.resolve(__dirname, 'dist'),
  29. publicPath: '/'
  30. },
  31. module: {
  32. rules: [
  33. {
  34. test: /\.css$/,
  35. use: [
  36. 'style-loader',
  37. 'css-loader'
  38. ]
  39. },
  40. {
  41. test: /\.(png|svg|jpg|gif)$/,
  42. use: [
  43. 'file-loader'
  44. ]
  45. },
  46. {
  47. test: /\.(woff|woff2|eot|ttf|otf)$/,
  48. use: [
  49. 'file-loader'
  50. ]
  51. },
  52. {
  53. test: /\.(csv|tsv)$/,
  54. use: [
  55. 'csv-loader'
  56. ]
  57. },
  58. {
  59. test: /\.xml$/,
  60. use: [
  61. 'xml-loader'
  62. ]
  63. }
  64. ],
  65. }
  66. };

下面代码需要注意的是 import printMe from ‘./print.js’; 如果你的引入依赖将包含你所想要拆分的文件时,此文件不被拆分。并且前一个文件加载过后,import(/ webpackChunkName: “lodash” / ‘lodash’),’./print.js文件不需要引入,直接使用即可。

  1. // index.js
  2. // import _ from 'lodash';
  3. import './style.css';
  4. import Icon from './icon.svg';
  5. import Data from './data.xml';
  6. // import printMe from './print.js';
  7. import { cube } from './math.js';
  8. function getComponent() {
  9. return import(/* webpackChunkName: "lodash" */ 'lodash').then(({ default: _ }) => {
  10. var element = document.createElement('div');
  11. element.innerHTML = _.join(['Hello', 'webpack'], ' ');
  12. return element;
  13. }).catch(error => 'An error occurred while loading the component');
  14. }
  15. getComponent().then(component => {
  16. document.body.appendChild(component);
  17. })

作为import()返回承诺,它可以与async函数一起使用。但是,这需要使用像Babel这样的预处理器和Syntax Dynamic Import Babel插件。以下是如何简化代码:

  1. async function getComponent() {
  2. var element = document.createElement('div');
  3. const { default: _ } = await import(/* webpackChunkName: "lodash" */ 'lodash');
  4. element.innerHTML = _.join(['Hello', 'webpack'], ' ');
  5. return element;
  6. }
  7. getComponent().then(component => {
  8. document.body.appendChild(component);
  9. });