渐进式配置webpack4单页面和多页面(三)

渐进式配置webpack4单页面和多页面

前言

使用包的版本css

webpack ->4.3.0
babel-loader ->8.0.5
npm ->6.4.1
webpack-cli ->3.3.1
复制代码

每一个章节对应一个demohtml

构建多页面配置

具体代码参考demo12node

新建多页面目录

新建module文件,约定module目录里面每一个文件目录必须有个html文件,还有一个与其名字相同的js文件做为入口文件。 react

建立变量函数

build文件夹里面的help.js里面新建方法webpack

/**
 * @description: 遍历文件夹里面的全部文件
 * @param {array} [路径地址]
 * @return: {文件名:文件地址}
 */
exports.getEntry = function getEntry(globPath) {
	var entries = {};
	if (typeof(globPath) != "object") {
			globPath = [globPath]
  }
	globPath.forEach((itemPath) => {
        // glob.sync 同步读取
		glob.sync(itemPath).forEach(function(entry) {
				entries[entry.substring(13, entry.lastIndexOf('.'))] = entry; // 13表明'./src/module/'
		});
	});
	return entries;
};
复制代码

引入多页面文件

webpack.base.js里面引入多页面入口文件

var entries = help.getEntry(['./src/module/**/*.js']); // 得到入口js文件
console.log(entries);
/**
打印结果
{ 'demo/demo': './src/module/demo/demo.js',
  'test/test': './src/module/test/test.js' }
**/
复制代码

添加到入口文件ios

entry:Object.assign({},{app:help.resolve('./app.js')},entries),
复制代码

webpack.base.js里面引入多页面的html文件

function concatHtmlWebpackPlugin() {
  var entriesHtml = help.getEntry(['./src/module/**/*.html']);
  console.log(entriesHtml)
  /**
  打印结果
  { 'demo/demo': './src/module/demo/demo.html',
  'test/test': './src/module/test/test.html' }
  **/
  var res = [];
  for (var i in entriesHtml) {
    var html = entriesHtml[i];
    var obj = new htmlWebpackPlugin({
      filename: '.' + html.substring(html.lastIndexOf('/')),
      template: html, //html模板路径
      inject: true, //容许插件修改哪些内容,包括head与body
      chunks: ['vendors',i],//i表明入口文件的key 指定注入某些入口文件
      minify: {
        // 压缩 HTML 文件
        removeComments: isPord, // 移除 HTML 中的注释
        collapseWhitespace: isPord, // 删除空白符与换行符
        minifyCSS: isPord // 压缩内联 css
      },
    })
    res.push(obj)
  }
  return res
}
复制代码

注入多页面git

plugins:[
    
    new htmlWebpackPlugin({
      filename:'index.html',
      template:'./index.html',
      inject:true,
      chunks: ['vendors','app'], // 指定注入某些入口文件
      minify: {
        // 压缩 HTML 文件
        removeComments: isPord, // 移除 HTML 中的注释
        collapseWhitespace: isPord, // 删除空白符与换行符
        minifyCSS: isPord // 压缩内联 css
      },
    })
  ].concat(concatHtmlWebpackPlugin())
复制代码

splitChunks 进行默认配置

optimization: {
    splitChunks: {
      chunks: 'async',
      minSize: 30000,
      maxSize: 0,
      minChunks: 1,
      maxAsyncRequests: 5,
      maxInitialRequests: 3,
      automaticNameDelimiter: '~',
      name: true,
      cacheGroups: {
        vendors: {
          test: /[\\/]node_modules[\\/]/,
          priority: -10
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true
        }
      }
    }
  },
复制代码

运行命令github

npm run dev
复制代码

能够正常运行

多页面拆包配置

具体代码参考demo12web

每一个页面的js文件引入各类包

src/module/demo/demo.js

import axios from 'axios';
import xlsx from 'xlsx';
import dropzone from 'dropzone';
import lodash from 'lodash';
console.log(lodash);
console.log(dropzone);
console.log(xlsx);
console.log(axios);
var s=document.createElement('div')
s.innerHTML='dome文件'
document.getElementById('app').appendChild(s);
复制代码

引入了lodash、dropzone、xlsx、axios这4个包。npm

src/module/test/test.js

import echarts from 'echarts';
import xlsx from 'xlsx';
import dropzone from 'dropzone';
console.log(dropzone);
console.log(xlsx);
console.log(echarts)
var s=document.createElement('div')
s.innerHTML='test文件'
document.getElementById('app').appendChild(s);
复制代码

引入了dropzone、xlsx、echarts这3个包。

app.js

import "regenerator-runtime/runtime";
import React from 'react';
import ReactDOM from 'react-dom';
import About from './src/view/about';
import Inbox from './src/view/inbox';
// import asyncComponent from './src/assets/js/AsyncComponent'
// const Inbox = asyncComponent(() => import( './src/view/inbox'));
// const About = asyncComponent(() => import( './src/view/about'));
import { BrowserRouter as Router, Switch, Redirect, Route, Link, HashRouter ,RouteChildren} from 'react-router-dom'
class App extends React.Component {
  render() {
    return (
      <div className="shopping-list">
      {this.props.children}
        <ul>
          <li><Link to="/about">About</Link></li>
          <li><Link to="/inbox">Inbox</Link></li>
        </ul>
      </div>
    );
  }
}

class Home extends React.Component {
  render() {
    return (
      <HashRouter>
        <Switch>
          <App>
            <Route path="/about" component={About} />
            <Route path="/inbox" component={Inbox} />
          </App>
        </Switch>
      </HashRouter>
    )
  }

}

ReactDOM.render(
  <Home />,
  document.getElementById('app')
);
复制代码

引入了react、react-dom这2个包。

拆包分析

demo.js与test.js 有使用相同的包dropzone和xlsx。 app.js 只使用了 react和react-dom。

splitChunks 进行默认配置。

optimization: {
    splitChunks: {
      chunks: 'all',
      minSize: 30000,
      maxSize: 0,
      minChunks: 1,
      maxAsyncRequests: 5,
      maxInitialRequests: 3,
      automaticNameDelimiter: '~',
      name: true,
      cacheGroups: {
        vendors: {
          name:'vendors',
          chunks: 'all',
          test: /[\\/]node_modules[\\/]/,
          priority: -10
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true
        }
      }
    }
  },
复制代码

直接打包

npm run build
复制代码
npm run server
复制代码

结果

首页有很大的一个包。

test.html也同样

demo.html也是同样。

总结

说明引入的包都打包到一个js文件了,每一个多页面都加载了多余的包。因此默认配置不能很好的进行多页面的拆包。

进行拆包优化配置

修改splitChunks代码

optimization: {
    splitChunks: {
      chunks: 'all',
      minSize: 30000,
      maxSize: 0,
      minChunks: 1,
      maxAsyncRequests: 5,
      maxInitialRequests: 3,
      automaticNameDelimiter: '~',
      name: true,
      cacheGroups: {
        reactVendors: { //reactVendors 来匹配react相关的包
          chunks: 'all',
          test: /(react|react-dom|react-dom-router)/,
          priority: 100,
          name: 'react',
        },
        commonVendors: { // commonVendors 来匹配xlsx和dropzone的包
          chunks: 'all',
          test: /(dropzone|xlsx)/,
          priority: 90,
          name: 'commonMode',
        },
        vendors: {
          name:'vendors',
          chunks: 'all',
          test: /[\\/]node_modules[\\/]/,
          priority: -10
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true
        }
      }
    }
  },
复制代码

多配置了commonVendors和reactVendors这两个匹配项目。 试试 可不能够。

npm run build
复制代码

从打包的状况 貌似能够了。拆包成功。

可是打开页面并无发现这些包有引入。

因此chunks没有引入包全部须要去引入。

不一样的入口文件引入不一样的chunks

因此 app.js 这个入口文件须要引入 react 这个chunks。

new htmlWebpackPlugin({
      filename:'index.html',
      template:'./index.html',
      inject:true,
      chunks: ['vendors','app','react'],
      minify: {
        // 压缩 HTML 文件
        removeComments: isPord, // 移除 HTML 中的注释
        collapseWhitespace: isPord, // 删除空白符与换行符
        minifyCSS: isPord // 压缩内联 css
      },
    })
  ].concat(concatHtmlWebpackPlugin())
复制代码

多页面须要引入 commonMode 这个chunks。

function concatHtmlWebpackPlugin() {
  var entriesHtml = help.getEntry(['./src/module/**/*.html']);
  console.log(entriesHtml)
  var res = [];
  for (var i in entriesHtml) {
    var html = entriesHtml[i];
    var obj = new htmlWebpackPlugin({
      filename: '.' + html.substring(html.lastIndexOf('/')),
      template: html, //html模板路径
      inject: true, //容许插件修改哪些内容,包括head与body
      chunks: ['vendors',i,'commonMode'],//i表明入口文件的key
      minify: {
        // 压缩 HTML 文件
        removeComments: isPord, // 移除 HTML 中的注释
        collapseWhitespace: isPord, // 删除空白符与换行符
        minifyCSS: isPord // 压缩内联 css
      },
    })
    res.push(obj)
  }
  return res
}
复制代码

配置完成后。

页面正常运行 而且拆包完成。
相关文章
相关标签/搜索