webpack多页应用配置脚手架

发布时间:2019-03-17

之前写了一个webpack多页应用的配置,只有一个webpack.config.js文件,实现了多入口配置打包css,js,资源文件处理。因为入口entry配置需要自己添加,HtmlWebpackPlugin有多少个页面也要自己添加。这样看来虽然配置是成功的,但过于机械化,是不可取的

为什么要进行多页应用配置?

我们都知道开发vue,react这些应用时,一般都只有一个入口文件。而且官方都提供了自己的脚手架。可谓是很繁琐,偏离自己实际开发的环境时,这些脚手架就不能满足我们的要求了。虽然也有很多别人写的多页配置,但是感觉配置模块分离过于严重,而且满足不了自己的需求,不适合新手学习使用。

很多传统网页的开发还是要写很多静态界面,比如我们公司,官网展示类的网站。如果要按照传统的开发模式,我们要为不同的页面添加css文件,js文件,这样大大的增加了工作量,而且很枯燥。而且不能使用es6,scss.
所以这个webpack多页配置就是为了解决这些问题,拥抱es6

完整配置:webpack-M-pages

读取页面,进行多入口配置

本着约定大于配置的原则,我们对页面文件的放置进行一定的约束。
保持html文件名与入口js文件名一致,使用glob模块,动态读取文件夹生成配置

└─pages //页面配置目录
        ├─index
        │      index.html
        │      index.js
        │      
        ├─pageA
        │      pageA.html
        │      pageA.js
        │      
        └─pageB
                pageB.html
                pageB.js

项目目录结构

│  .babelrc
│  .gitignore
│  .postcssrc.js
│  getEntrys.js
│  package-lock.json
│  package.json
│  README.md
│  webpack.config.js
│  
├─config
│      base.plugin.js //包含动态生成HtmlWebpackPlugin
│      entrys.js  //动态入口与HtmlWebpackPlugin动态生成
│      utils.js
│      
└─src
    ├─assets
    │  ├─css
    │  │  │  bootstrap.css
    │  │  │  index.scss
    │  │  │  
    │  │  ├─pageA
    │  │  │      a.css
    │  │  │      as.scss
    │  │  │      
    │  │  ├─pageB
    │  │  │      b.css
    │  │  │      bb.scss
    │  │  │      
    │  │  └─pageC
    │  │          c.css
    │  │          
    │  ├─fonts
    │  │      glyphicons-halflings-regular.eot
    │  │      glyphicons-halflings-regular.svg
    │  │      glyphicons-halflings-regular.ttf
    │  │      glyphicons-halflings-regular.woff
    │  │      glyphicons-halflings-regular.woff2
    │  │      
    │  └─img
    │          ph.jpg
    │          
    ├─common
    │  ├─css
    │  │      reset.css
    │  │      
    │  └─js
    │          common.js
    │          
    ├─js
    │  │  testm.js
    │  │  
    │  └─other
    │          a.js
    │          b.js
    │          
    ├─lib
    │      test.js
    │      
    └─pages //页面配置目录
        ├─index
        │      index.html
        │      index.js
        │      
        ├─pageA
        │      pageA.html
        │      pageA.js
        │      
        └─pageB
                pageB.html
                pageB.js
            

自动注入entry配置

webpack的entry配置是这样的

module.exports = { devtool: '#source-map', entry:{ index:'', about:'', home:'', ..... } }

动态读取html页面,配置多入口

//entrys.js var glob = require('glob') var path = require('path') var PAGES_DIR = path.resolve(__dirname, '../src/pages') exports.entries = function () { var entryFiles = glob.sync(PAGES_DIR + '/*/*.js') var resultEntry = {} entryFiles.forEach(filePath => { var filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.')) resultEntry[filename] = filePath }) return resultEntry }

这样我们的入口配置文件就可以这样简写了

const { entries } = require("./config/entrys"); module.exports = { devtool: '#source-map', entry: entries(), }

HtmlWebpackPlugin

这个其实就和自动注入entry配置一样,所以我们先看下 HtmlWebpackPlugin的配置

new HtmlWebpackPlugin({ template: 'index.html', filename: 'index.html', chunks: ["vendors",'index'], // hash:true, minify: { removeComments: true, collapseWhitespace: false //删除空白符与换行符 } });

动态配置 HtmlWebpackPlugin

//读取html文件 exports.htmlPages = function () { var entryHtmls = glob.sync(PAGES_DIR + '/*/*.html') var resultHtmlPages = [] entryHtmls.forEach(filePath => { var filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.')) var htmlPlugin = { template: filePath, filename: filename + '.html', chunks: filename, inject: true } resultHtmlPages.push(htmlPlugin) }) return resultHtmlPages }

遍历页面,添加配置

/*遍历页面,添加配置*/ let { htmlPages } = require("./entrys"); let pageArr = htmlPages(); pageArr.forEach(page => { const htmlPlugin = new HtmlWebpackPlugin({ template: page.template, filename: page.filename, chunks: ["vendors", page.chunks], // hash:true, minify: { removeComments: true, collapseWhitespace: false //删除空白符与换行符 } }); base_plugin.push(htmlPlugin); });

优化chunks

let chunksArr = []; pageArr.forEach(page => { chunksArr.push(page.chunks); }); new webpack.optimize.CommonsChunkPlugin({ name: "vendors", chunks: chunksArr, //提取公用模块 minChunks: Infinity }),

END