webpack 共用文件抽离?

发布于 2022-09-04 12:32:19 字数 5797 浏览 13 评论 0

需求:
在gulp或者grunt打包中:
1、共用库抽离:zepto、util.js、module.js(自行封装的业务模块等);当然还有common.css(实际开发中使用less编写)。一般我会抽离成库文件base.js、模块工具类util.js和common.css。
2、页面文件:page.js和page.css。

问题:

声明:使用vue2+vuex+vue-router2+ES6+LESS(SASS)+webpack2

1、我使用了vue-router2的路由懒加载。所以会对每一个页面生成一个chunk.js。(里面会包含当前页面css和js代码。当然还有import导入的工具类和模块代码,虽然这不是我想要的。)

2、JS:我目前已经使用CommonsChunkPlugin实现了第三方插件的抽离(主要是采用在app.js入口文件中导入解决)。但自行封装的ajax业务逻辑和util等,即通过具体页面import moduleobj from module 使用的模块代码在每一个chunk.js中有存在。可能有人说设置option.children=true;这样会把太多非共用封装的模块代码都打包到共用文件去了。
说了这么多,我只是感觉webpack没法想gulp或者grunt那样对每一个文件包括文件的内容进行精细化的控制。

3、CSS:目前我共用的common样式采用less编写。通过在入口页面import可以实现。但问题是iconfont图标库必须通过gulp转移到build目录。直接common.less中去引用iconfont.css会报错!同时页面自身的css目前都在chunk.js中。有人可能使用ExtractTextPlugin进行抽离。但还是不够精细。
我想应该每个页面抽离初一个样式文件page.css。然后一个公用的common.css。

一句话:就是怎么抽离共用的文件(共用插件库、业务模块库、页面逻辑、共用样式、页面样式)

当然很可能也是我对webpack还不熟悉,没法精细化控制。

附上webpack.base.js

"use strict";

var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');

const CONFIG = require('./config');
var projectRoot = CONFIG.projectRoot || path.resolve(__dirname, '../');
var _ENV = CONFIG.env || 'dev';//prod

module.exports = {
    devtool: _ENV != 'prod' ? '#eval-source-map' : false,
    context: __dirname,//
    entry: {
        app: path.join(projectRoot, './vue/app.js'),
        page: path.join(projectRoot, './vue/page.js')
    },
    output: {
        path: path.join(projectRoot, './build/vue-' + _ENV),
        publicPath: '',//'./build/vue-'+_ENV+'/',//path.join(__dirname, '../src/build/dev/')
        filename: '[name].js',
        chunkFilename: 'chunks/[name].chunk.js',
        // crossOriginLoading: 'anonymous'
    },
    resolve: {
        alias: {
            'vue$': 'vue/dist/vue.common.js',
            'vue-router$': 'vue-router/dist/vue-router.common.js'
        },
        modules: ["node_modules"],
        mainFiles: ["index", "app"],
        extensions: [".js", ".json", '.vue']
    },
    module: {
        rules: [
            {
                test: /\.vue$/,
                loader: 'vue-loader',
                options: {
                    loaders: {
                        // Since sass-loader (weirdly) has SCSS as its default parse mode, we map
                        // the "scss" and "sass" values for the lang attribute to the right configs here.
                        // other preprocessors should work out of the box, no loader config like this nessessary.
                        'scss': 'vue-style-loader!css-loader!sass-loader',
                        'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax',
                        'less': 'vue-style-loader!css-loader!less-loader'
                    }
                    // other vue-loader options go here
                }
            },
            {
                test: /\.js$/,
                loader: 'babel-loader',
                exclude: /node_modules/
            },
            {
                test: /\.less$/,
                loader: "style-loader!css-loader!less-loader"
            },
            {
                test: /\.scss$/,
                loaders: ["style-loader", "css-loader", "sass-loader"]
            },
            {
                test: /\.json$/,
                loader: 'json-loader'
            },
            {
                test: /\.html$/,
                loader: 'vue-html-loader'
            },
            {
                test: /\.(png|jpg|gif|svg)$/,
                loader: 'file-loader',
                options: {
                    name: '[name].[ext]?[hash]'
                }
            }
        ]
    },
    plugins: [
        //注入一些全局变量
        new webpack.DefinePlugin({
            _ENV_: _ENV,
            _VERSION_: JSON.stringify("1.0.0")
        }),
        new webpack.optimize.CommonsChunkPlugin({
            name: "commons",
            // (the commons chunk name)

            filename: "vueCommons.js",
            // (the filename of the commons chunk)

            minChunks: function(module,count){
                console.log(module.resource);//无法遍历到util.js和service.js(业务层ajax)
            },
            // (Modules must be shared between 3 entries)

            // chunks: ["pageA", "pageB"],
            // (Only use these entries)
            // children: true,
            // async: true,
        }),
        //可以和entry文件联合配置
        new HtmlWebpackPlugin({
            inject: false,
            title: 'vueJs of app',
            filename: 'app.html',
            template: '../vue/entry/template.ejs',
            scripts: ['./vueCommons.js', './app.js']
        }),
        new HtmlWebpackPlugin({
            inject: false,
            title: 'vueJs of page',
            filename: 'page.html',
            template: '../vue/entry/template.ejs',
            scripts: ['./vueCommons.js', './page.js']
        })
    ]

};

webpack.prod.js

"use strict";
var merge = require('webpack-merge');
var webpack = require('webpack');
var baseConfig = require('./webpack.base.js');


var prodConfig = merge.smart(baseConfig, {
    devtool: false,
    plugins: [
        //webpack plugins docs=>删除重复代码
        new webpack.optimize.DedupePlugin(),
        //压缩工具
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: true,
                drop_console:true,
                dead_code:true
            },
            mangle: {
                except: ['$']
            },
            output: {
                comments: false
            },
            sourceMap: false
        })

    ]

});

module.exports = prodConfig;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

苏璃陌 2022-09-11 12:32:19

common.js

exports.a = require('a')
exports.b = require('b')
exports.c = require('c')

clientX.js

// lazy load
require(['common'], (common) => {
  // do something with common.a or common.b or common.c
})

星巴克的钱直接赞赏我的文章吧

躲猫猫 2022-09-11 12:32:19
"use strict";

var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require("extract-text-webpack-plugin");

const CONFIG = require('./config');
var projectRoot = CONFIG.projectRoot || path.resolve(__dirname, '../');
var _ENV = CONFIG.env || 'dev';//prod

module.exports = {
    devtool: _ENV != 'prod' ? '#eval-source-map' : false,
    context: __dirname,//http://wxungang.github.io/1104/vue
    entry: {
        util: ['vue-router', path.join(projectRoot, './vue/service/service.js')],//需要抽离的业务工具类
        app: path.join(projectRoot, './vue/app.js'),
        page: path.join(projectRoot, './vue/page.js')
    },
    output: {
        path: path.join(projectRoot, './build/vue-' + _ENV),
        publicPath: '',//'./build/vue-'+_ENV+'/',//path.join(__dirname, '../src/build/dev/')
        filename: '[name].js',
        chunkFilename: 'chunks/[name].chunk.js',
        // crossOriginLoading: 'anonymous'
    },
    resolve: {
        alias: {
            'vue
: 'vue/dist/vue.common.js',
            'vue-router
: 'vue-router/dist/vue-router.common.js'
        },
        modules: ["node_modules"],
        mainFiles: ["index", "app"],
        extensions: [".js", ".json", '.vue']
    },
    module: {
        rules: [
            {
                test: /\.vue$/,
                loader: 'vue-loader',
                options: {
                    loaders: {
                        // Since sass-loader (weirdly) has SCSS as its default parse mode, we map
                        // the "scss" and "sass" values for the lang attribute to the right configs here.
                        // other preprocessors should work out of the box, no loader config like this nessessary.
                        'scss': 'vue-style-loader!css-loader!sass-loader',
                        'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax',
                        'less': 'vue-style-loader!css-loader!less-loader'
                    }
                    // other vue-loader options go here
                }
            },
            {
                test: /\.js$/,
                loader: 'babel-loader',
                exclude: /node_modules/
            },
            {
                test: /\.less$/,
                loader: "style-loader!css-loader!less-loader"
            },
            {
                test: /\.scss$/,
                loaders: ["style-loader", "css-loader", "sass-loader"]
            },
            {
                test: /\.json$/,
                loader: 'json-loader'
            },
            {
                test: /\.html$/,
                loader: 'vue-html-loader'
            },
            {
                test: /\.(png|jpg|gif|svg)$/,
                loader: 'file-loader',
                options: {
                    name: '[name].[ext]?[hash]'
                }
            }
        ]
    },
    plugins: [
        //注入一些全局变量
        new webpack.DefinePlugin({
            _ENV_: _ENV,
            _VERSION_: JSON.stringify("1.0.0")
        }),
        new webpack.optimize.CommonsChunkPlugin({
            name: ['util'],
            // (the commons chunk name)

            // filename: "vueCommons.js",
            // (the filename of the commons chunk)

            minChunks: Infinity,
            // (Modules must be shared between 3 entries)

            // chunks: ["pageA", "pageB"],
            // (Only use these entries)
            // children: true,
            // async: true,
        }),
        //可以和entry文件联合配置
        new HtmlWebpackPlugin({
            inject: false,
            title: 'vueJs of app',
            filename: 'app.html',
            template: '../vue/entry/template.ejs',
            scripts: ['./util.js', './app.js']
        }),
        new HtmlWebpackPlugin({
            inject: false,
            title: 'vueJs of page',
            filename: 'page.html',
            template: '../vue/entry/template.ejs',
            scripts: ['./util.js', './page.js']
        })
    ]

};
萝莉病 2022-09-11 12:32:19
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurenceOrderPlugin()
倒带 2022-09-11 12:32:19

你的意思是不是想说ajax 和utils 的文件打包在一起,页面有引用到加载,没引用到就不加载?

这应该是用按需加载实现的吧,用require.ensure语法引入ajax 和utils 试试。

旧竹 2022-09-11 12:32:19

我写了一个 Demo 应该满足你的需求:https://github.com/d-band/vue...

其中 dool 是我们写的一个组件对 webpack 封装了下,支持 entry 是 css 或 less 文件。另外如果用 vue 不建议用 zepto 了。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文