찾다

 >  Q&A  >  본문

javascript - Webpack Vue2 multiple entry项目 Webpack打包时如何排除ElementUI(JS/CSS)?

团队正在做OA前端项目(ElementUI全组件入口JS文件引入),项目前端功能模块组件太多,采用Webpack Vue2 multiple entry 多页面入口方式开发,开发调试运行正常,每个入口Html都是相同的布局导航主界面框架(延迟加载各自相关的组件模块)Webpack打包时想抽离出ElementUI(JS/CSS)做直接CDN引入,JS可以通过配置 externals: { 'element-ui':'ElementUI'}排除,但是CSS文件还是写入到了每个入口页面各自独立的CSS文件,请支招...

配置环境
Webpack ^2.2.1
Vue ^2.2.2
ElementUI ^1.2.5

webpack.base.conf

var path = require('path')
var webpack = require('webpack')

var config = require('../config')
var utils = require('./utils')
var entris = require('./entris')

var projectRoot = path.resolve(__dirname, '../')
var env = process.env.NODE_ENV
// check env & config/index.js to decide weither to enable CSS Sourcemaps for the
// various preprocessor loaders added to vue-loader at the end of this file
var cssSourceMapDev = (env === 'development' && config.dev.cssSourceMap)
var cssSourceMapProd = (env === 'production' && config.build.productionSourceMap)
var useCssSourceMap = cssSourceMapDev || cssSourceMapProd
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var baseWebpackConfig = {
    entry: {
        vendor: ['vue','vuex','vue-router']
    },
    output: {
        path: config.build.assetsRoot,
        publicPath: process.env.NODE_ENV === 'production'
            ? config.build.assetsPublicPath
            : config.dev.assetsPublicPath,
        filename: 'js/[name].js'
    },
    externals: {        
        'element-ui':'ElementUI'
    },
    resolve: {
        extensions: ['.js', '.vue'],/* require时省略的扩展名,如:require('module') 不需要module.js*/
        modules: [
            path.join(__dirname, '../node_modules'),
        ],
        alias: {
            '~src': path.resolve(__dirname, '../src'),
            '~api': path.resolve(__dirname, '../src/api/index'),
            '~api-config': path.resolve(__dirname, '../src/api/config'),
            '~components': path.resolve(__dirname, '../src/components'),
            '~pages': path.resolve(__dirname, '../src/pages'),
            '~store': path.resolve(__dirname, '../src/store'),
            '~utils': path.resolve(__dirname, '../src/utils')
        }
    },
    resolveLoader: {
        modules: [path.join(__dirname, '../node_modules')]
    },
    module: {
        rules: [
            {
                test: /\.vue$/,
                loader: 'eslint-loader',
                enforce: "pre",
                include: projectRoot,
                exclude: /node_modules/
            }, {
                test: /\.js$/,
                loader: 'eslint-loader',
                enforce: "pre",
                include: projectRoot,
                exclude: /node_modules/
            }, {
                test: /\.vue$/,
                loader: 'vue-loader'
            }, {
                test: /\.js$/,
                loader: 'babel-loader',
                include: projectRoot,
                exclude: /node_modules/
            }, {
                test: /\.json$/,
                loader: 'json-loader'
            }, {
                test: /\.html$/,
                loader: 'vue-html-loader'
            }, {
                test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
                loader: 'url-loader',
                query: {
                    limit: 10000,
                    name: utils.assetsPath('img/[name].[hash:7].[ext]')
                }
            }, {
                test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
                loader: 'url-loader',
                query: {
                    limit: 10000,
                    name: utils.assetsPath('css/fonts/[name].[hash:7].[ext]')
                }
            }
        ]
    },
    plugins: [
        new webpack.ProvidePlugin({$: 'jquery', jQuery: 'jquery', 'window.jQuery': 'jquery'}),
        new ExtractTextPlugin(utils.assetsPath('css/[name].css?[contenthash:7]'))
    ]
}
baseWebpackConfig.entry = Object.assign(baseWebpackConfig.entry, entris)
module.exports = baseWebpackConfig

webpack.prod.conf

var path = require("path")
var config = require('../config')
var utils = require('./utils')
var entris = require('./entris')
var webpack = require('webpack')
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var HtmlWebpackPlugin = require('html-webpack-plugin')

config.build.productionSourceMap = false

baseWebpackConfig = merge(baseWebpackConfig, {
    module: {
        rules: utils.styleLoaders({sourceMap: config.build.productionSourceMap, extract: true})
    },
    devtool: config.build.productionSourceMap
        ? '#source-map'
        : false,
    output: {
        path: config.build.assetsRoot,
        filename: utils.assetsPath('js/[name].js?[chunkhash:7]'),
        chunkFilename: utils.assetsPath('js/[id].js?[chunkhash:7]')
    },
    plugins: [
        new webpack.DefinePlugin({
            'process.env': {
                NODE_ENV: '"production"'
            }
        }),
        new webpack.optimize.CommonsChunkPlugin({
            name: 'vendor',
            minChunks: function(module, count) {
                return (module.resource && /\.js$/.test(module.resource) && module.resource.indexOf(path.join(__dirname, '../node_modules')) === 0)
            }
        }),        
        new webpack.optimize.CommonsChunkPlugin({name: 'manifest', chunks: ['vendor']}),
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false
            }
        }),
        new ExtractTextPlugin(utils.assetsPath('css/[name].css?[contenthash:7]')),
        new webpack.LoaderOptionsPlugin({
            minimize: true,
            options: {
                context: __dirname,
                vue: {
                    loaders: utils.cssLoaders({sourceMap: config.build.productionSourceMap, extract: true})
                }
            }
        })
    ]
})

Object.keys(entris).forEach(function(entry) {
    baseWebpackConfig.plugins.push(new HtmlWebpackPlugin({
        chunks: [ 'manifest', 'vendor', entry ],
        filename: entry + '.html',
        template: 'src/template/index.html',
        inject: true,
        minify: {
            removeComments: true,
            collapseWhitespace: true,
            removeAttributeQuotes: true
        }
    }))
})

module.exports = baseWebpackConfig

utils.js

var path = require('path')
var config = require('../config')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
exports.assetsPath = function(_path) {
    var assetsSubDirectory = process.env.NODE_ENV === 'production' ? config.build.assetsSubDirectory : config.dev.assetsSubDirectory
    return path.posix.join(assetsSubDirectory, _path)
}

exports.cssLoaders = function(options) {
    options = options || {}
        // generate loader string to be used with extract text plugin
    function generateLoaders(loaders) {
        loaders = ['css', 'postcss'].concat(loaders)
        var sourceLoader = loaders.map(function(loader) {
            var extraParamChar
            if (/\?/.test(loader)) {
                loader = loader.replace(/\?/, '-loader?')
                extraParamChar = '&'
            } else {
                loader = loader + '-loader'
                extraParamChar = '?'
            }
            return loader + (options.sourceMap ? extraParamChar + 'sourceMap' : '')            
        }).join('!')

        if (options.extract) {
            return ExtractTextPlugin.extract({ fallback: 'vue-style-loader', use: sourceLoader })
        } else {
            return ['vue-style-loader', sourceLoader].join('!')
        }
    }

    // http://vuejs.github.io/vue-loader/configurations/extract-css.html
    return {
        css: generateLoaders([]),
        postcss: generateLoaders([]),
        less: generateLoaders(['less']),
        sass: generateLoaders(['sass?indentedSyntax']),
        scss: generateLoaders(['sass'])
    }
}

// Generate loaders for standalone style files (outside of .vue)
exports.styleLoaders = function(options) {
    var output = []
    var loaders = exports.cssLoaders(options)
    for (var extension in loaders) {
        var loader = loaders[extension]
        output.push({
            test: new RegExp('\\.' + extension + '$'),
            loader: loader
        })
    }
    return output
}
PHPzPHPz2776일 전855

모든 응답(1)나는 대답할 것이다

  • 黄舟

    黄舟2017-04-11 13:00:24

    已经自己解决

    회신하다
    0
  • 취소회신하다