UNPKG

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