UNPKG

4.8 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
8/** @typedef {import("webpack-sources").Source} Source */
9/** @typedef {import("./ChunkGraph")} ChunkGraph */
10/** @typedef {import("./CodeGenerationResults")} CodeGenerationResults */
11/** @typedef {import("./Compilation")} Compilation */
12/** @typedef {import("./ConcatenationScope")} ConcatenationScope */
13/** @typedef {import("./DependencyTemplate")} DependencyTemplate */
14/** @typedef {import("./DependencyTemplates")} DependencyTemplates */
15/** @typedef {import("./Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */
16/** @typedef {import("./ModuleGraph")} ModuleGraph */
17/** @typedef {import("./NormalModule")} NormalModule */
18/** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
19/** @typedef {import("./util/Hash")} Hash */
20/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
21
22/**
23 * @typedef {Object} GenerateContext
24 * @property {DependencyTemplates} dependencyTemplates mapping from dependencies to templates
25 * @property {RuntimeTemplate} runtimeTemplate the runtime template
26 * @property {ModuleGraph} moduleGraph the module graph
27 * @property {ChunkGraph} chunkGraph the chunk graph
28 * @property {Set<string>} runtimeRequirements the requirements for runtime
29 * @property {RuntimeSpec} runtime the runtime
30 * @property {ConcatenationScope=} concatenationScope when in concatenated module, information about other concatenated modules
31 * @property {CodeGenerationResults=} codeGenerationResults code generation results of other modules (need to have a codeGenerationDependency to use that)
32 * @property {string} type which kind of code should be generated
33 * @property {function(): Map<string, any>=} getData get access to the code generation data
34 */
35
36/**
37 * @typedef {Object} UpdateHashContext
38 * @property {NormalModule} module the module
39 * @property {ChunkGraph} chunkGraph
40 * @property {RuntimeSpec} runtime
41 */
42
43/**
44 *
45 */
46class Generator {
47 static byType(map) {
48 return new ByTypeGenerator(map);
49 }
50
51 /* istanbul ignore next */
52 /**
53 * @abstract
54 * @param {NormalModule} module fresh module
55 * @returns {Set<string>} available types (do not mutate)
56 */
57 getTypes(module) {
58 const AbstractMethodError = require("./AbstractMethodError");
59 throw new AbstractMethodError();
60 }
61
62 /* istanbul ignore next */
63 /**
64 * @abstract
65 * @param {NormalModule} module the module
66 * @param {string=} type source type
67 * @returns {number} estimate size of the module
68 */
69 getSize(module, type) {
70 const AbstractMethodError = require("./AbstractMethodError");
71 throw new AbstractMethodError();
72 }
73
74 /* istanbul ignore next */
75 /**
76 * @abstract
77 * @param {NormalModule} module module for which the code should be generated
78 * @param {GenerateContext} generateContext context for generate
79 * @returns {Source} generated code
80 */
81 generate(
82 module,
83 { dependencyTemplates, runtimeTemplate, moduleGraph, type }
84 ) {
85 const AbstractMethodError = require("./AbstractMethodError");
86 throw new AbstractMethodError();
87 }
88
89 /**
90 * @param {NormalModule} module module for which the bailout reason should be determined
91 * @param {ConcatenationBailoutReasonContext} context context
92 * @returns {string | undefined} reason why this module can't be concatenated, undefined when it can be concatenated
93 */
94 getConcatenationBailoutReason(module, context) {
95 return `Module Concatenation is not implemented for ${this.constructor.name}`;
96 }
97
98 /**
99 * @param {Hash} hash hash that will be modified
100 * @param {UpdateHashContext} updateHashContext context for updating hash
101 */
102 updateHash(hash, { module, runtime }) {
103 // no nothing
104 }
105}
106
107class ByTypeGenerator extends Generator {
108 constructor(map) {
109 super();
110 this.map = map;
111 this._types = new Set(Object.keys(map));
112 }
113
114 /**
115 * @param {NormalModule} module fresh module
116 * @returns {Set<string>} available types (do not mutate)
117 */
118 getTypes(module) {
119 return this._types;
120 }
121
122 /**
123 * @param {NormalModule} module the module
124 * @param {string=} type source type
125 * @returns {number} estimate size of the module
126 */
127 getSize(module, type) {
128 const t = type || "javascript";
129 const generator = this.map[t];
130 return generator ? generator.getSize(module, t) : 0;
131 }
132
133 /**
134 * @param {NormalModule} module module for which the code should be generated
135 * @param {GenerateContext} generateContext context for generate
136 * @returns {Source} generated code
137 */
138 generate(module, generateContext) {
139 const type = generateContext.type;
140 const generator = this.map[type];
141 if (!generator) {
142 throw new Error(`Generator.byType: no generator specified for ${type}`);
143 }
144 return generator.generate(module, generateContext);
145 }
146}
147
148module.exports = Generator;