UNPKG

4.85 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 * @property {RuntimeTemplate=} runtimeTemplate
42 */
43
44/**
45 *
46 */
47class Generator {
48 static byType(map) {
49 return new ByTypeGenerator(map);
50 }
51
52 /* istanbul ignore next */
53 /**
54 * @abstract
55 * @param {NormalModule} module fresh module
56 * @returns {Set<string>} available types (do not mutate)
57 */
58 getTypes(module) {
59 const AbstractMethodError = require("./AbstractMethodError");
60 throw new AbstractMethodError();
61 }
62
63 /* istanbul ignore next */
64 /**
65 * @abstract
66 * @param {NormalModule} module the module
67 * @param {string=} type source type
68 * @returns {number} estimate size of the module
69 */
70 getSize(module, type) {
71 const AbstractMethodError = require("./AbstractMethodError");
72 throw new AbstractMethodError();
73 }
74
75 /* istanbul ignore next */
76 /**
77 * @abstract
78 * @param {NormalModule} module module for which the code should be generated
79 * @param {GenerateContext} generateContext context for generate
80 * @returns {Source} generated code
81 */
82 generate(
83 module,
84 { dependencyTemplates, runtimeTemplate, moduleGraph, type }
85 ) {
86 const AbstractMethodError = require("./AbstractMethodError");
87 throw new AbstractMethodError();
88 }
89
90 /**
91 * @param {NormalModule} module module for which the bailout reason should be determined
92 * @param {ConcatenationBailoutReasonContext} context context
93 * @returns {string | undefined} reason why this module can't be concatenated, undefined when it can be concatenated
94 */
95 getConcatenationBailoutReason(module, context) {
96 return `Module Concatenation is not implemented for ${this.constructor.name}`;
97 }
98
99 /**
100 * @param {Hash} hash hash that will be modified
101 * @param {UpdateHashContext} updateHashContext context for updating hash
102 */
103 updateHash(hash, { module, runtime }) {
104 // no nothing
105 }
106}
107
108class ByTypeGenerator extends Generator {
109 constructor(map) {
110 super();
111 this.map = map;
112 this._types = new Set(Object.keys(map));
113 }
114
115 /**
116 * @param {NormalModule} module fresh module
117 * @returns {Set<string>} available types (do not mutate)
118 */
119 getTypes(module) {
120 return this._types;
121 }
122
123 /**
124 * @param {NormalModule} module the module
125 * @param {string=} type source type
126 * @returns {number} estimate size of the module
127 */
128 getSize(module, type) {
129 const t = type || "javascript";
130 const generator = this.map[t];
131 return generator ? generator.getSize(module, t) : 0;
132 }
133
134 /**
135 * @param {NormalModule} module module for which the code should be generated
136 * @param {GenerateContext} generateContext context for generate
137 * @returns {Source} generated code
138 */
139 generate(module, generateContext) {
140 const type = generateContext.type;
141 const generator = this.map[type];
142 if (!generator) {
143 throw new Error(`Generator.byType: no generator specified for ${type}`);
144 }
145 return generator.generate(module, generateContext);
146 }
147}
148
149module.exports = Generator;