66"use strict" ;
77
88const { pathToFileURL } = require ( "url" ) ;
9+ const { SyncBailHook } = require ( "tapable" ) ;
10+ const Compilation = require ( "../Compilation" ) ;
911const ModuleDependencyWarning = require ( "../ModuleDependencyWarning" ) ;
1012const {
1113 JAVASCRIPT_MODULE_TYPE_AUTO ,
@@ -31,21 +33,52 @@ const ConstDependency = require("./ConstDependency");
3133/** @typedef {import("../javascript/JavascriptParser") } Parser */
3234/** @typedef {import("../javascript/JavascriptParser").Range } Range */
3335/** @typedef {import("../javascript/JavascriptParser").Members } Members */
36+ /** @typedef {import("../javascript/JavascriptParser").DestructuringAssignmentProperty } DestructuringAssignmentProperty */
3437
3538const getCriticalDependencyWarning = memoize ( ( ) =>
3639 require ( "./CriticalDependencyWarning" )
3740) ;
3841
3942const PLUGIN_NAME = "ImportMetaPlugin" ;
4043
44+ /**
45+ * @typedef {object } ImportMetaPluginHooks
46+ * @property {SyncBailHook<[DestructuringAssignmentProperty], string | void> } propertyInDestructuring
47+ */
48+
49+ /** @type {WeakMap<Compilation, ImportMetaPluginHooks> } */
50+ const compilationHooksMap = new WeakMap ( ) ;
51+
4152class ImportMetaPlugin {
53+ /**
54+ * @param {Compilation } compilation the compilation
55+ * @returns {ImportMetaPluginHooks } the attached hooks
56+ */
57+ static getCompilationHooks ( compilation ) {
58+ if ( ! ( compilation instanceof Compilation ) ) {
59+ throw new TypeError (
60+ "The 'compilation' argument must be an instance of Compilation"
61+ ) ;
62+ }
63+ let hooks = compilationHooksMap . get ( compilation ) ;
64+ if ( hooks === undefined ) {
65+ hooks = {
66+ propertyInDestructuring : new SyncBailHook ( [ "property" ] )
67+ } ;
68+ compilationHooksMap . set ( compilation , hooks ) ;
69+ }
70+ return hooks ;
71+ }
72+
4273 /**
4374 * @param {Compiler } compiler compiler
4475 */
4576 apply ( compiler ) {
4677 compiler . hooks . compilation . tap (
4778 PLUGIN_NAME ,
4879 ( compilation , { normalModuleFactory } ) => {
80+ const hooks = ImportMetaPlugin . getCompilationHooks ( compilation ) ;
81+
4982 /**
5083 * @param {NormalModule } module module
5184 * @returns {string } file url
@@ -136,8 +169,15 @@ class ImportMetaPlugin {
136169 }
137170
138171 let str = "" ;
139- for ( const { id : prop } of referencedPropertiesInDestructuring ) {
140- switch ( prop ) {
172+ for ( const prop of referencedPropertiesInDestructuring ) {
173+ const value = hooks . propertyInDestructuring . call ( prop ) ;
174+
175+ if ( value ) {
176+ str += value ;
177+ continue ;
178+ }
179+
180+ switch ( prop . id ) {
141181 case "url" :
142182 str += `url: ${ importMetaUrl ( ) } ,` ;
143183 break ;
@@ -146,8 +186,8 @@ class ImportMetaPlugin {
146186 break ;
147187 default :
148188 str += `[${ JSON . stringify (
149- prop
150- ) } ]: ${ importMetaUnknownProperty ( [ prop ] ) } ,`;
189+ prop . id
190+ ) } ]: ${ importMetaUnknownProperty ( [ prop . id ] ) } ,`;
151191 break ;
152192 }
153193 }
@@ -222,7 +262,12 @@ class ImportMetaPlugin {
222262 . tap ( PLUGIN_NAME , ( expr , members ) => {
223263 // keep import.meta.env unknown property
224264 // don't evaluate import.meta.env.UNKNOWN_PROPERTY -> undefined.UNKNOWN_PROPERTY
225- if ( members [ 0 ] === "env" ) {
265+ // `dirname` and `filename` logic in NodeStuffPlugin
266+ if (
267+ members [ 0 ] === "env" ||
268+ members [ 0 ] === "dirname" ||
269+ members [ 0 ] === "filename"
270+ ) {
226271 return true ;
227272 }
228273 const dep = new ConstDependency (
0 commit comments