1. 程式人生 > >webpack搭建多頁面應用優化版

webpack搭建多頁面應用優化版

專案前期定的只有兩頁面所以entry入口檔案直接寫死的,後來又加了幾個頁面,還是遍歷處理一下,不用一直改配置檔案。

改過之後的專案結構

思路:使用fs外掛讀取pages下的目錄名稱,遍歷得到pages下的每個目錄的名稱。然後入口檔案配置每個目錄下的index.js,html模版為每個目錄下的index.html,然後每個js通過require引入相對應的index.scss。

下面單獨列出來

/**
 * 遍歷資料夾,把所有檔案的路徑拼到一個數組裡,然後通過map獲取到每一個檔案
 * 
 */
function getFolders(dir) {
    return fs.readdirSync(dir)
        .filter(
function(file) { return fs.statSync(path.join(dir, file)).isDirectory(); }); }
//獲取pages下面的資料夾
const folders = getFolders(pagePath);

/**
 * 遍歷資料夾自動新增entry
 */
function addEntry(){
    let entryObj = {};
    folders.forEach(f=>{
        entryObj[f] = `${pagePath+f}/index.js`;
    });
    
return entryObj; }
//自動新增html
folders.forEach(f=>{
    let htmlPlugin = {
        filename:`${f}.html`,
        template:`${pagePath+f}/index.html`,
        favicon:'./images/favicon.ico',
        chunks:[`${f}`],
        inject: true,
        hash:true,
        minify: {
            removeComments: 
true, collapseWhitespace: true } } config.plugins.push(new HtmlWebpackPlugin(htmlPlugin)); })

以下是優化的完整程式碼

//引入路徑外掛
const path = require('path');
//引入遍歷資料夾的外掛
const fs = require('fs');
//引入匯出html外掛
const HtmlWebpackPlugin = require('html-webpack-plugin');
//引入清除外掛
const CleanWebpackPlugin = require('clean-webpack-plugin');
//引入匯出css外掛
const ExtractTextPlugin = require('extract-text-webpack-plugin');
//引入webpack
const webpack  = require('webpack');
//引入壓縮css的外掛
const optimizeCss = require('optimize-css-assets-webpack-plugin');
//引入cssnano外掛
const cssnano = require('cssnano');
//相容ie8的外掛
const es3ifyPlugin = require('es3ify-webpack-plugin');
//引入js壓縮外掛
const uglifyjs = require('uglifyjs-webpack-plugin');
//定義webpak.config.js相對於pages的路徑
const pagePath = './pages/';

/**
 * 遍歷資料夾,把所有檔案的路徑拼到一個數組裡,然後通過map獲取到每一個檔案
 * 
 */
function getFolders(dir) {
    return fs.readdirSync(dir)
        .filter(function(file) {
            return fs.statSync(path.join(dir, file)).isDirectory();
        });
}
//獲取pages下面的資料夾
const folders = getFolders(pagePath);

/**
 * 遍歷資料夾自動新增entry
 */
function addEntry(){
    let entryObj = {};
    folders.forEach(f=>{
        entryObj[f] = `${pagePath+f}/index.js`;
    });
    return entryObj;
}


//webpack配置內容
const config = {
    //入口
    entry:addEntry(),
    //便於除錯
    devtool:'inline-source-map',
    //服務
    devServer:{
        contentBase:'build'
    },
    //loader模組
    module:{
        rules: [
           {//ES6
            test:/\.js$/,
            loader:'babel-loader',
            // exclude:__dirname+'node_modules',//不對這個進行babel轉換,這裡邊已經打包好,這樣能減少打包時間
            // include:__dirname+'src'這裡的src是你要編譯的js檔案的目錄,
            exclude:path.resolve(__dirname,'node_modules'),
            include:path.resolve(__dirname,'../webapp'),
            query:{//若在package.json中定義了這個presets,則這邊可以刪掉
                presets:['es2015','es2015-loose'],
                ignore :[ './lib/webuploader/*.js']
            }
          },
          {
            test: /.js$/,
            enforce: 'post', // post-loader處理
            loader: 'es3ify-loader'
          },
          {//Jquery
            test: require.resolve('jquery'),
            use: [{
              loader: 'expose-loader',
              options: 'jQuery'
            },{
              loader: 'expose-loader',
              options: '$'
            }]
          },
          {//CSS
              test:/\.css/,
              use:ExtractTextPlugin.extract({
                  use:['css-loader']
              })
          },
          {//Sass
              test:/\.scss/,
              use:ExtractTextPlugin.extract({
                  fallback:"style-loader",
                  use:['css-loader','sass-loader']
              },)
          },
          {//處理模組html
            test: /\.html$/,
            use: 'html-loader'
          },
          {//圖片
            test: /\.(jpg|png|gif)$/,
            use: {
                loader: 'file-loader',
                options: {
                    outputPath: 'images'
                }
            }
          },
          //字型圖示
            {
            test: /\.(eot|svg|ttf|woff|woff2)\w*/,
            loader: 'file-loader'
          },
          {
            test: /\.htc$/,            
            loader: 'file-loader'
          },
          {
            test: /\.swf$/,            
            loader: 'url-loader'
          }
        ]
    },
    //外掛
    plugins: [        
        //全域性引入jquery
        new webpack.ProvidePlugin({
          $: "jquery",
          jQuery: "jquery",
          jquery: "jquery",
          "window.jQuery": "jquery",
          identifier: ['es5-shim', 'es5-shim/es5-sham'],
        }),
        //清空build檔案下的多餘檔案
        new CleanWebpackPlugin(['build']),
        //將css單獨打包外掛
        new ExtractTextPlugin({
          filename:"[name].css",//制定編譯後的檔名稱
          allChunks:true,//把分割的塊分別打包
        }),
        //壓縮css
        new optimizeCss({
          assetNameRegExp: /\.style\.css$/g,
          cssProcessor: cssnano,
          cssProcessorOptions: { discardComments: { removeAll: true } },
          canPrint: true
        }),
        //壓縮js
        new uglifyjs({
            parallel:true,
            include:/\/node_modules/,
            uglifyOptions:{
                ie8:true
            }
        }),
        new es3ifyPlugin()
    ],
    //壓縮優化css
    optimization: {
        // minimize: true,
        minimizer: [new optimizeCss({})]
    },
    //出口
    output:{
        filename: '[name].bundle.js',
        path: path.resolve(__dirname,'build')        
    }
}

//自動新增html
folders.forEach(f=>{
    let htmlPlugin = {
        filename:`${f}.html`,
        template:`${pagePath+f}/index.html`,
        favicon:'./images/favicon.ico',
        chunks:[`${f}`],
        inject: true,
        hash:true,
        minify: {
            removeComments: true,
            collapseWhitespace: true
        }
    }
    config.plugins.push(new HtmlWebpackPlugin(htmlPlugin));
})

module.exports = config;