UNPKG

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