Skip to content

Commit

Permalink
add ImportMetaContextPlugin
Browse files Browse the repository at this point in the history
  • Loading branch information
vankop committed Mar 1, 2022
1 parent b89f397 commit d3c5d35
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 22 deletions.
2 changes: 2 additions & 0 deletions lib/WebpackOptionsApply.js
Expand Up @@ -35,6 +35,7 @@ const ResolverCachePlugin = require("./cache/ResolverCachePlugin");

const CommonJsPlugin = require("./dependencies/CommonJsPlugin");
const HarmonyModulesPlugin = require("./dependencies/HarmonyModulesPlugin");
const ImportMetaContextPlugin = require("./dependencies/ImportMetaContextPlugin");
const ImportMetaPlugin = require("./dependencies/ImportMetaPlugin");
const ImportPlugin = require("./dependencies/ImportPlugin");
const LoaderPlugin = require("./dependencies/LoaderPlugin");
Expand Down Expand Up @@ -361,6 +362,7 @@ class WebpackOptionsApply extends OptionsApply {
new RequireEnsurePlugin().apply(compiler);
new RequireContextPlugin().apply(compiler);
new ImportPlugin().apply(compiler);
new ImportMetaContextPlugin().apply(compiler);
new SystemPlugin().apply(compiler);
new ImportMetaPlugin().apply(compiler);
new URLPlugin().apply(compiler);
Expand Down
59 changes: 59 additions & 0 deletions lib/dependencies/ImportMetaContextPlugin.js
@@ -0,0 +1,59 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Ivan Kopeykin @vankop
*/

"use strict";

const ContextElementDependency = require("./ContextElementDependency");
const ImportMetaContextDependency = require("./ImportMetaContextDependency");
const ImportMetaContextDependencyParserPlugin = require("./ImportMetaContextDependencyParserPlugin");

/** @typedef {import("../../declarations/WebpackOptions").ResolveOptions} ResolveOptions */
/** @typedef {import("../Compiler")} Compiler */

class ImportMetaContextPlugin {
/**
* Apply the plugin
* @param {Compiler} compiler the compiler instance
* @returns {void}
*/
apply(compiler) {
compiler.hooks.compilation.tap(
"RequireContextPlugin",
(compilation, { contextModuleFactory, normalModuleFactory }) => {
compilation.dependencyFactories.set(
ImportMetaContextDependency,
contextModuleFactory
);
compilation.dependencyTemplates.set(
ImportMetaContextDependency,
new ImportMetaContextDependency.Template()
);
compilation.dependencyFactories.set(
ContextElementDependency,
normalModuleFactory
);

const handler = (parser, parserOptions) => {
if (
parserOptions.importMetaContext !== undefined &&
!parserOptions.importMetaContext
)
return;

new ImportMetaContextDependencyParserPlugin().apply(parser);
};

normalModuleFactory.hooks.parser
.for("javascript/auto")
.tap("ImportMetaContextPlugin", handler);
normalModuleFactory.hooks.parser
.for("javascript/esm")
.tap("ImportMetaContextPlugin", handler);
}
);
}
}

module.exports = ImportMetaContextPlugin;
20 changes: 0 additions & 20 deletions lib/dependencies/RequireContextPlugin.js
Expand Up @@ -7,8 +7,6 @@

const { cachedSetProperty } = require("../util/cleverMerge");
const ContextElementDependency = require("./ContextElementDependency");
const ImportMetaContextDependency = require("./ImportMetaContextDependency");
const ImportMetaContextDependencyParserPlugin = require("./ImportMetaContextDependencyParserPlugin");
const RequireContextDependency = require("./RequireContextDependency");
const RequireContextDependencyParserPlugin = require("./RequireContextDependencyParserPlugin");

Expand Down Expand Up @@ -36,14 +34,6 @@ class RequireContextPlugin {
RequireContextDependency,
new RequireContextDependency.Template()
);
compilation.dependencyFactories.set(
ImportMetaContextDependency,
contextModuleFactory
);
compilation.dependencyTemplates.set(
ImportMetaContextDependency,
new ImportMetaContextDependency.Template()
);

compilation.dependencyFactories.set(
ContextElementDependency,
Expand All @@ -60,16 +50,6 @@ class RequireContextPlugin {
new RequireContextDependencyParserPlugin().apply(parser);
};

const handlerImportMeta = (parser, parserOptions) => {
new ImportMetaContextDependencyParserPlugin().apply(parser);
};

normalModuleFactory.hooks.parser
.for("javascript/auto")
.tap("RequireContextPlugin", handlerImportMeta);
normalModuleFactory.hooks.parser
.for("javascript/esm")
.tap("RequireContextPlugin", handlerImportMeta);
normalModuleFactory.hooks.parser
.for("javascript/auto")
.tap("RequireContextPlugin", handler);
Expand Down
11 changes: 9 additions & 2 deletions test/cases/chunks/context-weak/index.js
@@ -1,4 +1,11 @@
it("should not bundle context requires with asyncMode === 'weak'", function() {
var contextRequire = require.context(".", false, /two/, "weak");
expect(function() {
contextRequire("./two")
}).toThrowError(/not available/);
});

it("should not bundle context requires with asyncMode === 'weak' using import.meta.webpackContext", function() {
const contextRequire = import.meta.webpackContext(".", {
recursive: false,
regExp: /two/,
Expand All @@ -10,13 +17,13 @@ it("should not bundle context requires with asyncMode === 'weak'", function() {
});

it("should find module with asyncMode === 'weak' when required elsewhere", function() {
const contextRequire = require.context(".", false, /.+/, "weak");
var contextRequire = require.context(".", false, /.+/, "weak");
expect(contextRequire("./three")).toBe(3);
require("./three"); // in a real app would be served as a separate chunk
});

it("should find module with asyncMode === 'weak' when required elsewhere (recursive)", function() {
const contextRequire = require.context(".", true, /.+/, "weak");
var contextRequire = require.context(".", true, /.+/, "weak");
expect(contextRequire("./dir/four")).toBe(4);
require("./dir/four"); // in a real app would be served as a separate chunk
});

0 comments on commit d3c5d35

Please sign in to comment.