UNPKG

5.52 kBJavaScriptView Raw
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5
6"use strict";
7
8const { RawSource } = require("webpack-sources");
9const OriginalSource = require("webpack-sources").OriginalSource;
10const Module = require("./Module");
11
12/** @typedef {import("webpack-sources").Source} Source */
13/** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */
14/** @typedef {import("./Chunk")} Chunk */
15/** @typedef {import("./ChunkGraph")} ChunkGraph */
16/** @typedef {import("./Compilation")} Compilation */
17/** @typedef {import("./Dependency").UpdateHashContext} UpdateHashContext */
18/** @typedef {import("./Module").CodeGenerationContext} CodeGenerationContext */
19/** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */
20/** @typedef {import("./Module").NeedBuildContext} NeedBuildContext */
21/** @typedef {import("./RequestShortener")} RequestShortener */
22/** @typedef {import("./ResolverFactory").ResolverWithOptions} ResolverWithOptions */
23/** @typedef {import("./WebpackError")} WebpackError */
24/** @typedef {import("./util/Hash")} Hash */
25/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
26
27const TYPES = new Set(["runtime"]);
28
29class RuntimeModule extends Module {
30 /**
31 * @param {string} name a readable name
32 * @param {number=} stage an optional stage
33 */
34 constructor(name, stage = 0) {
35 super("runtime");
36 this.name = name;
37 this.stage = stage;
38 this.buildMeta = {};
39 this.buildInfo = {};
40 /** @type {Compilation} */
41 this.compilation = undefined;
42 /** @type {Chunk} */
43 this.chunk = undefined;
44 this.fullHash = false;
45 /** @type {string} */
46 this._cachedGeneratedCode = undefined;
47 }
48
49 /**
50 * @param {Compilation} compilation the compilation
51 * @param {Chunk} chunk the chunk
52 * @returns {void}
53 */
54 attach(compilation, chunk) {
55 this.compilation = compilation;
56 this.chunk = chunk;
57 }
58
59 /**
60 * @returns {string} a unique identifier of the module
61 */
62 identifier() {
63 return `webpack/runtime/${this.name}`;
64 }
65
66 /**
67 * @param {RequestShortener} requestShortener the request shortener
68 * @returns {string} a user readable identifier of the module
69 */
70 readableIdentifier(requestShortener) {
71 return `webpack/runtime/${this.name}`;
72 }
73
74 /**
75 * @param {NeedBuildContext} context context info
76 * @param {function(WebpackError=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
77 * @returns {void}
78 */
79 needBuild(context, callback) {
80 return callback(null, false);
81 }
82
83 /**
84 * @param {WebpackOptions} options webpack options
85 * @param {Compilation} compilation the compilation
86 * @param {ResolverWithOptions} resolver the resolver
87 * @param {InputFileSystem} fs the file system
88 * @param {function(WebpackError=): void} callback callback function
89 * @returns {void}
90 */
91 build(options, compilation, resolver, fs, callback) {
92 // do nothing
93 // should not be called as runtime modules are added later to the compilation
94 callback();
95 }
96
97 /**
98 * @param {Hash} hash the hash used to track dependencies
99 * @param {UpdateHashContext} context context
100 * @returns {void}
101 */
102 updateHash(hash, context) {
103 hash.update(this.name);
104 hash.update(`${this.stage}`);
105 try {
106 if (this.fullHash) {
107 // Do not use getGeneratedCode here, because i. e. compilation hash might be not
108 // ready at this point. We will cache it later instead.
109 hash.update(this.generate());
110 } else {
111 hash.update(this.getGeneratedCode());
112 }
113 } catch (err) {
114 hash.update(err.message);
115 }
116 super.updateHash(hash, context);
117 }
118
119 /**
120 * @returns {Set<string>} types available (do not mutate)
121 */
122 getSourceTypes() {
123 return TYPES;
124 }
125
126 /**
127 * @param {CodeGenerationContext} context context for code generation
128 * @returns {CodeGenerationResult} result
129 */
130 codeGeneration(context) {
131 const sources = new Map();
132 const generatedCode = this.getGeneratedCode();
133 if (generatedCode) {
134 sources.set(
135 "runtime",
136 this.useSourceMap || this.useSimpleSourceMap
137 ? new OriginalSource(generatedCode, this.identifier())
138 : new RawSource(generatedCode)
139 );
140 }
141 return {
142 sources,
143 runtimeRequirements: null
144 };
145 }
146
147 /**
148 * @param {string=} type the source type for which the size should be estimated
149 * @returns {number} the estimated size of the module (must be non-zero)
150 */
151 size(type) {
152 try {
153 const source = this.getGeneratedCode();
154 return source ? source.length : 0;
155 } catch (e) {
156 return 0;
157 }
158 }
159
160 /* istanbul ignore next */
161 /**
162 * @abstract
163 * @returns {string} runtime code
164 */
165 generate() {
166 const AbstractMethodError = require("./AbstractMethodError");
167 throw new AbstractMethodError();
168 }
169
170 /**
171 * @returns {string} runtime code
172 */
173 getGeneratedCode() {
174 if (this._cachedGeneratedCode) {
175 return this._cachedGeneratedCode;
176 }
177 return (this._cachedGeneratedCode = this.generate());
178 }
179
180 /**
181 * @returns {boolean} true, if the runtime module should get it's own scope
182 */
183 shouldIsolate() {
184 return true;
185 }
186}
187
188/**
189 * Runtime modules without any dependencies to other runtime modules
190 */
191RuntimeModule.STAGE_NORMAL = 0;
192
193/**
194 * Runtime modules with simple dependencies on other runtime modules
195 */
196RuntimeModule.STAGE_BASIC = 5;
197
198/**
199 * Runtime modules which attach to handlers of other runtime modules
200 */
201RuntimeModule.STAGE_ATTACH = 10;
202
203/**
204 * Runtime modules which trigger actions on bootstrap
205 */
206RuntimeModule.STAGE_TRIGGER = 20;
207
208module.exports = RuntimeModule;