简体   繁体   中英

Custom module directories in chunk splitting doesn't work in Webpack

I am building a project with webpack and I want to remove duplicated custom materialize.js library with the following config:

const path = require('path');
const webpack = require('webpack');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

module.exports = {
    entry: {
        frontend: './src/AppBundle/Resources/js/Frontend/frontend.js',
        panel: ['./src/AppBundle/Resources/js/Panel/forms.js', './src/AppBundle/Resources/js/Panel/vue/main.js']
    },
    output: {
        filename: '[name].min.js',
        path: path.join(__dirname, 'web/js')
    },
    optimization: {
        splitChunks: {
            cacheGroups: {
                commons: {
                    test: /node_modules|src\/AppBundle\/Resources\/js\/Vendor/,
                    name: 'vendor',
                    chunks: 'all'
                }
            }
        }
    },
    module: {
        rules: [
            {
                test: /\.vue$/,
                loader: 'vue-loader'
            },
            {
                test: /\.js$/,
                loader: 'babel-loader'
            },
            {
                test: /\.css$/,
                use: [
                    'vue-style-loader',
                    'css-loader'
                ]
            }
        ]
    },
    resolve: {
        extensions: ['*', '.js', '.vue', '.json']
    },
    plugins: [
        new webpack.ProvidePlugin({
            $: "jquery",
            jQuery: "jquery",
            'window.$': 'jquery',
            'window.jQuery': 'jquery'
        }),
        new VueLoaderPlugin(),
        new BundleAnalyzerPlugin()
    ]
};

Thus, I would like to get three files: frontend, panel and vendors (this one with vue.js, jquery.js and materialize.js)

Here is my source folder structure:

Frontend
|_frontend.js
Panel
|_forms.js
|_vue
  |_(...).js
Vendor
|_materialize.js

In frontend.js and forms.js I have added jQuery:

window.$ = window.jQuery = require('jquery');

Bacause jQuery is taken from node_modules, it is appended using optimization.splitChunks in vendor.js

Unfortunately I need to have custom materialize.js file (modified, not form package in node_module), so I applied it in optimization.splitChunks, and add to previous two files as well:

require('../Vendor/materialize');

It works correctry, except it is appended twice in frontend.js and panel.js, not in vendor.js. I would to have it just in vendor.js.

BundleAnalyzerPlugin shows output like this: 在此处输入图片说明

I thought, I can add materialize.js as the vendor entry point (and get rid of require('../Vendor/materialize') from previous two files), but unfortunately it doesn't work, ie materialize functions are not found, eg :

...
Uncaught TypeError: $(...).pickadate is not a function
...

In html I have scripts one after another:

<script type="text/javascript" src="/js/vendor.min.js"></script>
<script type="text/javascript" src="/js/frontend.min.js"></script>

It was working right without webpack, but now I don't know how to make it to working correctry?

I've already solved it. The problem was with regex. SplitChunksPlugin did not resolved it:

test: /node_modules|src\/AppBundle\/Resources\/js\/Vendor/,

In a case of having two directories of chunks, the best way out is to create two separate cache groups respectively for each directory and take advantage of path.resolve function:

optimization: {
    splitChunks: {
        cacheGroups: {
            commons: {
                test: path.resolve('node_modules'),
                name: 'vendor',
                chunks: 'all'
            },
            materialize: {
                test: path.resolve('src/AppBundle/Resources/js/Vendor'),
                name: 'vendor',
                chunks: 'all'
            }
        }
    }
},

Final output:

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM