55
66"use strict" ;
77
8+ const InitFragment = require ( "./InitFragment" ) ;
89const {
910 JAVASCRIPT_MODULE_TYPE_AUTO ,
1011 JAVASCRIPT_MODULE_TYPE_DYNAMIC ,
@@ -14,6 +15,7 @@ const RuntimeGlobals = require("./RuntimeGlobals");
1415const WebpackError = require ( "./WebpackError" ) ;
1516const ConstDependency = require ( "./dependencies/ConstDependency" ) ;
1617const BasicEvaluatedExpression = require ( "./javascript/BasicEvaluatedExpression" ) ;
18+ const JavascriptModulesPlugin = require ( "./javascript/JavascriptModulesPlugin" ) ;
1719const {
1820 toConstantDependency,
1921 evaluateToString
@@ -24,103 +26,121 @@ const GetFullHashRuntimeModule = require("./runtime/GetFullHashRuntimeModule");
2426/** @typedef {import("./Compiler") } Compiler */
2527/** @typedef {import("./javascript/JavascriptParser") } JavascriptParser */
2628
27- /* eslint-disable camelcase */
28- const REPLACEMENTS = {
29- __webpack_require__ : {
30- expr : RuntimeGlobals . require ,
31- req : [ RuntimeGlobals . require ] ,
32- type : "function" ,
33- assign : false
34- } ,
35- __webpack_public_path__ : {
36- expr : RuntimeGlobals . publicPath ,
37- req : [ RuntimeGlobals . publicPath ] ,
38- type : "string" ,
39- assign : true
40- } ,
41- __webpack_base_uri__ : {
42- expr : RuntimeGlobals . baseURI ,
43- req : [ RuntimeGlobals . baseURI ] ,
44- type : "string" ,
45- assign : true
46- } ,
47- __webpack_modules__ : {
48- expr : RuntimeGlobals . moduleFactories ,
49- req : [ RuntimeGlobals . moduleFactories ] ,
50- type : "object" ,
51- assign : false
52- } ,
53- __webpack_chunk_load__ : {
54- expr : RuntimeGlobals . ensureChunk ,
55- req : [ RuntimeGlobals . ensureChunk ] ,
56- type : "function" ,
57- assign : true
58- } ,
59- __non_webpack_require__ : {
60- expr : "require" ,
61- req : null ,
62- type : undefined , // type is not known, depends on environment
63- assign : true
64- } ,
65- __webpack_nonce__ : {
66- expr : RuntimeGlobals . scriptNonce ,
67- req : [ RuntimeGlobals . scriptNonce ] ,
68- type : "string" ,
69- assign : true
70- } ,
71- __webpack_hash__ : {
72- expr : `${ RuntimeGlobals . getFullHash } ()` ,
73- req : [ RuntimeGlobals . getFullHash ] ,
74- type : "string" ,
75- assign : false
76- } ,
77- __webpack_chunkname__ : {
78- expr : RuntimeGlobals . chunkName ,
79- req : [ RuntimeGlobals . chunkName ] ,
80- type : "string" ,
81- assign : false
82- } ,
83- __webpack_get_script_filename__ : {
84- expr : RuntimeGlobals . getChunkScriptFilename ,
85- req : [ RuntimeGlobals . getChunkScriptFilename ] ,
86- type : "function" ,
87- assign : true
88- } ,
89- __webpack_runtime_id__ : {
90- expr : RuntimeGlobals . runtimeId ,
91- req : [ RuntimeGlobals . runtimeId ] ,
92- assign : false
93- } ,
94- "require.onError" : {
95- expr : RuntimeGlobals . uncaughtErrorHandler ,
96- req : [ RuntimeGlobals . uncaughtErrorHandler ] ,
97- type : undefined , // type is not known, could be function or undefined
98- assign : true // is never a pattern
99- } ,
100- __system_context__ : {
101- expr : RuntimeGlobals . systemContext ,
102- req : [ RuntimeGlobals . systemContext ] ,
103- type : "object" ,
104- assign : false
105- } ,
106- __webpack_share_scopes__ : {
107- expr : RuntimeGlobals . shareScopeMap ,
108- req : [ RuntimeGlobals . shareScopeMap ] ,
109- type : "object" ,
110- assign : false
111- } ,
112- __webpack_init_sharing__ : {
113- expr : RuntimeGlobals . initializeSharing ,
114- req : [ RuntimeGlobals . initializeSharing ] ,
115- type : "function" ,
116- assign : true
117- }
118- } ;
119- /* eslint-enable camelcase */
29+ /**
30+ * @param {boolean } module true if ES module
31+ * @param {string } importMetaName `import.meta` name
32+ * @returns {Record<string, {expr: string, req: string[], type?: string, assign: boolean}> } replacements
33+ */
34+ function getReplacements ( module , importMetaName ) {
35+ return {
36+ __webpack_require__ : {
37+ expr : RuntimeGlobals . require ,
38+ req : [ RuntimeGlobals . require ] ,
39+ type : "function" ,
40+ assign : false
41+ } ,
42+ __webpack_public_path__ : {
43+ expr : RuntimeGlobals . publicPath ,
44+ req : [ RuntimeGlobals . publicPath ] ,
45+ type : "string" ,
46+ assign : true
47+ } ,
48+ __webpack_base_uri__ : {
49+ expr : RuntimeGlobals . baseURI ,
50+ req : [ RuntimeGlobals . baseURI ] ,
51+ type : "string" ,
52+ assign : true
53+ } ,
54+ __webpack_modules__ : {
55+ expr : RuntimeGlobals . moduleFactories ,
56+ req : [ RuntimeGlobals . moduleFactories ] ,
57+ type : "object" ,
58+ assign : false
59+ } ,
60+ __webpack_chunk_load__ : {
61+ expr : RuntimeGlobals . ensureChunk ,
62+ req : [ RuntimeGlobals . ensureChunk ] ,
63+ type : "function" ,
64+ assign : true
65+ } ,
66+ __non_webpack_require__ : {
67+ expr : module
68+ ? `__WEBPACK_EXTERNAL_createRequire(${ importMetaName } .url)`
69+ : "require" ,
70+ req : null ,
71+ type : undefined , // type is not known, depends on environment
72+ assign : true
73+ } ,
74+ __webpack_nonce__ : {
75+ expr : RuntimeGlobals . scriptNonce ,
76+ req : [ RuntimeGlobals . scriptNonce ] ,
77+ type : "string" ,
78+ assign : true
79+ } ,
80+ __webpack_hash__ : {
81+ expr : `${ RuntimeGlobals . getFullHash } ()` ,
82+ req : [ RuntimeGlobals . getFullHash ] ,
83+ type : "string" ,
84+ assign : false
85+ } ,
86+ __webpack_chunkname__ : {
87+ expr : RuntimeGlobals . chunkName ,
88+ req : [ RuntimeGlobals . chunkName ] ,
89+ type : "string" ,
90+ assign : false
91+ } ,
92+ __webpack_get_script_filename__ : {
93+ expr : RuntimeGlobals . getChunkScriptFilename ,
94+ req : [ RuntimeGlobals . getChunkScriptFilename ] ,
95+ type : "function" ,
96+ assign : true
97+ } ,
98+ __webpack_runtime_id__ : {
99+ expr : RuntimeGlobals . runtimeId ,
100+ req : [ RuntimeGlobals . runtimeId ] ,
101+ assign : false
102+ } ,
103+ "require.onError" : {
104+ expr : RuntimeGlobals . uncaughtErrorHandler ,
105+ req : [ RuntimeGlobals . uncaughtErrorHandler ] ,
106+ type : undefined , // type is not known, could be function or undefined
107+ assign : true // is never a pattern
108+ } ,
109+ __system_context__ : {
110+ expr : RuntimeGlobals . systemContext ,
111+ req : [ RuntimeGlobals . systemContext ] ,
112+ type : "object" ,
113+ assign : false
114+ } ,
115+ __webpack_share_scopes__ : {
116+ expr : RuntimeGlobals . shareScopeMap ,
117+ req : [ RuntimeGlobals . shareScopeMap ] ,
118+ type : "object" ,
119+ assign : false
120+ } ,
121+ __webpack_init_sharing__ : {
122+ expr : RuntimeGlobals . initializeSharing ,
123+ req : [ RuntimeGlobals . initializeSharing ] ,
124+ type : "function" ,
125+ assign : true
126+ }
127+ } ;
128+ }
120129
121130const PLUGIN_NAME = "APIPlugin" ;
122131
132+ /**
133+ * @typedef {Object } APIPluginOptions
134+ * @property {boolean } [module] the output filename
135+ */
136+
123137class APIPlugin {
138+ /**
139+ * @param {APIPluginOptions } [options] options
140+ */
141+ constructor ( options = { } ) {
142+ this . options = options ;
143+ }
124144 /**
125145 * Apply the plugin
126146 * @param {Compiler } compiler the compiler instance
@@ -130,6 +150,12 @@ class APIPlugin {
130150 compiler . hooks . compilation . tap (
131151 PLUGIN_NAME ,
132152 ( compilation , { normalModuleFactory } ) => {
153+ const { importMetaName } = compilation . outputOptions ;
154+ const REPLACEMENTS = getReplacements (
155+ this . options . module ,
156+ importMetaName
157+ ) ;
158+
133159 compilation . dependencyTemplates . set (
134160 ConstDependency ,
135161 new ConstDependency . Template ( )
@@ -152,18 +178,43 @@ class APIPlugin {
152178 return true ;
153179 } ) ;
154180
181+ const hooks = JavascriptModulesPlugin . getCompilationHooks ( compilation ) ;
182+
183+ hooks . renderModuleContent . tap (
184+ PLUGIN_NAME ,
185+ ( source , module , renderContext ) => {
186+ if ( module . buildInfo . needCreateRequire ) {
187+ const chunkInitFragments = [
188+ new InitFragment (
189+ 'import { createRequire as __WEBPACK_EXTERNAL_createRequire } from "module";\n' ,
190+ InitFragment . STAGE_HARMONY_IMPORTS ,
191+ 0 ,
192+ "external module node-commonjs"
193+ )
194+ ] ;
195+
196+ renderContext . chunkInitFragments . push ( ...chunkInitFragments ) ;
197+ }
198+
199+ return source ;
200+ }
201+ ) ;
202+
155203 /**
156204 * @param {JavascriptParser } parser the parser
157205 */
158206 const handler = parser => {
159207 Object . keys ( REPLACEMENTS ) . forEach ( key => {
160208 const info = REPLACEMENTS [ key ] ;
161- parser . hooks . expression
162- . for ( key )
163- . tap (
164- PLUGIN_NAME ,
165- toConstantDependency ( parser , info . expr , info . req )
166- ) ;
209+ parser . hooks . expression . for ( key ) . tap ( PLUGIN_NAME , expression => {
210+ const dep = toConstantDependency ( parser , info . expr , info . req ) ;
211+
212+ if ( key === "__non_webpack_require__" && this . options . module ) {
213+ parser . state . module . buildInfo . needCreateRequire = true ;
214+ }
215+
216+ return dep ( expression ) ;
217+ } ) ;
167218 if ( info . assign === false ) {
168219 parser . hooks . assign . for ( key ) . tap ( PLUGIN_NAME , expr => {
169220 const err = new WebpackError ( `${ key } must not be assigned` ) ;
0 commit comments