Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider adding dynamic import's webpackMode as a configuration option, or eval the comment contents to get value #5029

Closed
mayani opened this issue Jun 7, 2017 · 6 comments · Fixed by #15494
Projects

Comments

@mayani
Copy link

mayani commented Jun 7, 2017

Do you want to request a feature or report a bug?

Feature Request
Add webpackMode as a config. option OR eval comment in dynamic import before using it's value.

What is the current behavior?
webpackMode defaults to "lazy", it can be overridden through a comment as /* webpackMode: "eager" */

If the current behavior is a bug, please provide the steps to reproduce.

What is the expected behavior?
Ability to add webpackMode in config file, so preferred value in order of preference would be comment.webpackMode, config.webpackMode, webpackDefault.webpackMode

If this is a feature request, what is motivation or use case for changing the behavior?

Hot Module Replace works well with asynchronously imports. However, Hot Reload is unable to reload state for such code. Example: Using async. loaded components with React Hot Loader, where the component's are not refreshed. Only suitable approach seems to require loading code synchronously in development.

Adding webpackMode in config. could be an approach to fix this. i.e. Not specifying webpackMode in comment to use "lazy" in prod. and "eager" in development.

Alternative approach would be to eval webpackMode value. i.e.
/* webpackMode: process.env.NODE_ENV == "production" ? "lazy" : "eager" */

Please mention other relevant information such as the browser version, Node.js version, webpack version and Operating System.

Node 6.9.1
NPM 4.1.1
Webpack 2.6.1

@webpack-bot
Copy link
Contributor

This issue had no activity for at least three months.

It's subject to automatic issue closing if there is no activity in the next 15 days.

@alexander-akait
Copy link
Member

bump

@grafikri
Copy link

+1 bump

@nford88
Copy link

nford88 commented Aug 26, 2021

  • bump also.

I want to create a local build where all dynamic imports are not chunked and minimised into one file. Currently this works when I pass "eager" manually as a Magic Comment, but I cannot pass via an env file. Have also tried to define the variable as a Webpack plugin but again no luck.

Working, but hardcoded -

route: () => import(/* webpackMode: "eager" */ "./Newsletter.vue").then(ent => ent.default)

Wanted solution

route: () => import(/* /* webpackMode: process.env.NODE_ENV == "local_build" ? "eager" : "lazy" */ */ "./Newsletter.vue").then(ent => ent.default)

@droobertzka
Copy link

+1 bump

I have a real world use case for a 3rd party script which some customers would prefer and get better perfornace from a single file/request while others would prefer and gain better performance from code splitting. A global setting would allow us to use the exact same source and webpack config and get the desired output via a simple CLI arg.

If anyone is aware of another way to accomplish this same goal, I would love to hear about it.

@droobertzka
Copy link

The eager-imports-webpack-plugin from #8644 comes pretty close to filling this use case. I made some minor modifications and it works like a charm:

DynamicImportModePlugin.js

const validWebpackModes = ['lazy', 'lazy-once', 'eager', 'weak'];

module.exports = class DynamicImportModePlugin {
    constructor(webpackMode) {
        if (webpackMode && !validWebpackModes.includes(webpackMode)) {
            throw new Error(
                `Invalid webpackMode provided to DynamicImportModePlugin. Must be one of ${validWebpackModes.join(
                    ', '
                )}`
            );
        }
        this.webpackMode = webpackMode;
    }

    apply(compiler) {
        if (!this.webpackMode) {
            return;
        }

        const webpackMode = this.webpackMode;
        console.log(
            `DynamicImportModePlugin: Overriding dynamic imports to use '${webpackMode}' webpackMode`
        );

        compiler.hooks.compilation.tap(
            'DynamicImportModePlugin',
            (compilation, { normalModuleFactory }) => {
                ['javascript/auto', 'javascript/dynamic', 'javascript/esm'].forEach(type => {
                    normalModuleFactory.hooks.parser
                        .for(type)
                        .tap('DynamicImportModePlugin', parser => {
                            const oldParseCommentOptions = parser.parseCommentOptions;

                            parser.parseCommentOptions = function () {
                                const { options, ...rest } = oldParseCommentOptions.apply(
                                    parser,
                                    arguments
                                );

                                return {
                                    options: {
                                        ...options,
                                        webpackMode,
                                    },
                                    ...rest,
                                };
                            };
                        });
                });
            }
        );
    }
};

webpack.config.js

const DynamicImportModePlugin = require('./DynamicImportModePlugin')

module.exports = (env, argv) => ({
  // ...
  plugins: [
    new DynamicImportModePlugin(env.webpackMode),
  ],
})

Build Single Bundle (webpackMode: eager):

npx webpack --env webpackMode=eager

Default Build Behavior (split into chunks based on libraries, runtime, and dynamic imports):

npx webpack

Tested with webpack v5.64.4.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Development

Successfully merging a pull request may close this issue.

6 participants