多頁面應用的前端架構

前提

  • 數據管理平臺包含了多個後臺項目,後臺項目均使用vue做爲開發框架。
  • 子項目存在公共頭部,須要統一管理維護。
  • 子項目存在公共的依賴(如vuevuexvue-router等),公共依賴包能夠統一維護。
  • 子項目存在公共存在公共的配置文件例如postcss.config.js須要統一維護。

解決方案一

在一個項目中,使用 entry配置多個html文件來實現多頁面應用

存在的利弊:css

  • 配置簡單
  • 打包效率低下
  • 靈活性差
  • 須要維護多個html文件

解決方案二(採用)

使用 thinkjs統一維護每一個項目的 template.html,併爲頭部注入用戶信息,而且單獨構建一個 common項目,統一維護第三方依賴。

存在的利弊:html

  • 配置繁瑣
  • 打包效率高
  • 靈活性好
  • 只需維護一個html文件

項目目錄

├─src
│  ├─bootstrap
│  ├─config
│  ├─controller
│  ├─logic
│  └─model
├─view
│  └─index                            //模板文件目錄
└─vue_project                                
    |—package.json                    //統一維護全部依賴
    ├─asset_manage                    //子項目目錄
    ├─common                        //打包公共組件項目
    ├─postcss.config.js             //公用的配置文件

配置介紹

common配置介紹

打包主要配置介紹:vue

插件 描述
webpack.DllPlugin vendor依賴中的庫、文件打包(依賴的庫取的是package.dependencies的值)
extract-text-webpack-plugin css單獨提取出來,打包成一個.css文件
assets-webpack-plugin webpack.DllPlugin打包生成的文件的文件名保存爲一個.json文件。方便子項目引用。
optimize-css-assets-webpack-plugin 壓縮打包後的.css文件
module.exports = {
    mode: 'production',
    entry: {
        vendor: [...Object.keys(package.dependencies), './css/element-css/index.css', './css/index.postcss'],
    },
    devtool: "source-map",
    output: {
        path: path.join(__dirname, '../vendor'),
        filename: 'dll.[name]_[hash:6].js',
        library: '[name]_[hash:6]'
    },
    module: {
        rules: [{
                test: /\.css$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: 'css-loader'
                })
            },
            {
                test: /\.postcss$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: [{
                        loader: 'css-loader',
                        options: {
                            importLoaders: 1
                        }
                    }, 'postcss-loader', ]
                })
            },
            {
                test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
                use: 'url-loader'
            },
        ]
    },
    plugins: [
        new webpack.DllPlugin({
            path: path.join(__dirname, '../vendor', '[name]-manifest.json'),
            name: '[name]_[hash:6]',
            context: path.join(__dirname, '../../'), // 執行的上下文環境,對以後DllReferencePlugin有用
        }),
        new ExtractTextPlugin('[name]_[hash:6].css'),
        new AssetsPlugin({
            filename: 'bundle-config.json',
            path: path.join(__dirname, '../vendor')
        }),
        new OptimizeCssAssetsPlugin({
            assetNameRegExp: /\.css$/g,
            cssProcessor: require('cssnano'),
            cssProcessorOptions: {
                parser: require('postcss-safe-parser'),
                discardComments: {
                    removeAll: true
                },
            },
            canPrint: true
        })
    ]
}

vue-cli3配置介紹

vue-cli3的配置文件被封裝在了npm模塊 @vue/cli-service 中可以使用 vue inspect > output.js進行查看
插件 描述
webpack.DllReferencePlugin 將第三方依賴的索引id與對應的第三方依賴具體位置告知webpack
add-asset-html-webpack-plugin common中生成的bundle-config.json文件中的依賴文件注入html-webpack-plugin的模板中
const webpackConfig = {
    configureWebpack: {
        plugins: [
            new webpack.DllReferencePlugin({
                context: path.join(__dirname, '../../'),
                manifest
            }),
            new AddAssetHtmlPlugin([{
                    filepath: require.resolve(`../vendor/${bundleConfig.vendor.js}`),
                    includeSourcemap: false
                },
                {
                    typeOfAsset: 'css',
                    filepath: require.resolve(`../vendor/${bundleConfig.vendor.css}`),
                    includeSourcemap: false
                }
            ])
        ]
    },
    chainWebpack: config => {
        config.resolve.alias.store.delete('vue$');
        config.plugin('copy').tap(args => {
            args[0][0].from = './public';
            args[0][0].to = 'public';
            args[0][0].ignore = ['.*'];
            return args;
        });
        config.plugin('define').tap(args => {
            args[0]['process.env']['BUILD_ENV'] = "'" + process.env.BUILD_ENV + "'";
            return args;
        });
        config.module.rule('postcss').oneOf('vue').use('postcss').loader('postcss-loader').options({
            config: {
                path: path.join(__dirname, '../../')
            }
        });
    },
}

依賴統一管理

若是各自項目的打包依賴分佈在各自項目中,依然會增長維護成本以及依賴安裝的打包成本

這裏就須要理解node查找依賴的邏輯。經過module.paths能夠看到node查找依賴時的,順序node

[ 'E:\\datamanagement\\vue_project\\asset_manage\\repl\\node_modules',
  'E:\\datamanagement\\vue_project\\asset_manage\\node_modules',
  'E:\\datamanagement\\vue_project\\node_modules',
  'E:\\datamanagement\\node_modules',
  'E:\\node_modules',
  'C:\\Users\\18044854\\.node_modules',
  'C:\\Users\\18044854\\.node_libraries',
  'C:\\Program Files\\nodejs\\lib\\node' ]

node會從當前目錄的node_modules一級一級的向上查找,
因此咱們只須要將全部依賴安裝在common和vue的父級目錄便可webpack

相關文章
相關標籤/搜索