UNPKG

4.5 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 { ConcatSource } = require("webpack-sources");
9const ExternalModule = require("../ExternalModule");
10const Template = require("../Template");
11const AbstractLibraryPlugin = require("./AbstractLibraryPlugin");
12
13/** @typedef {import("webpack-sources").Source} Source */
14/** @typedef {import("../../declarations/WebpackOptions").LibraryOptions} LibraryOptions */
15/** @typedef {import("../../declarations/WebpackOptions").LibraryType} LibraryType */
16/** @typedef {import("../Chunk")} Chunk */
17/** @typedef {import("../Compilation").ChunkHashContext} ChunkHashContext */
18/** @typedef {import("../Compiler")} Compiler */
19/** @typedef {import("../javascript/JavascriptModulesPlugin").RenderContext} RenderContext */
20/** @typedef {import("../util/Hash")} Hash */
21/** @template T @typedef {import("./AbstractLibraryPlugin").LibraryContext<T>} LibraryContext<T> */
22
23/**
24 * @typedef {Object} AmdLibraryPluginOptions
25 * @property {LibraryType} type
26 * @property {boolean=} requireAsWrapper
27 */
28
29/**
30 * @typedef {Object} AmdLibraryPluginParsed
31 * @property {string} name
32 */
33
34/**
35 * @typedef {AmdLibraryPluginParsed} T
36 * @extends {AbstractLibraryPlugin<AmdLibraryPluginParsed>}
37 */
38class AmdLibraryPlugin extends AbstractLibraryPlugin {
39 /**
40 * @param {AmdLibraryPluginOptions} options the plugin options
41 */
42 constructor(options) {
43 super({
44 pluginName: "AmdLibraryPlugin",
45 type: options.type
46 });
47 this.requireAsWrapper = options.requireAsWrapper;
48 }
49
50 /**
51 * @param {LibraryOptions} library normalized library option
52 * @returns {T | false} preprocess as needed by overriding
53 */
54 parseOptions(library) {
55 const { name } = library;
56 if (this.requireAsWrapper) {
57 if (name) {
58 throw new Error(
59 `AMD library name must be unset. ${AbstractLibraryPlugin.COMMON_LIBRARY_NAME_MESSAGE}`
60 );
61 }
62 } else {
63 if (name && typeof name !== "string") {
64 throw new Error(
65 `AMD library name must be a simple string or unset. ${AbstractLibraryPlugin.COMMON_LIBRARY_NAME_MESSAGE}`
66 );
67 }
68 }
69 return {
70 name: /** @type {string=} */ (name)
71 };
72 }
73
74 /**
75 * @param {Source} source source
76 * @param {RenderContext} renderContext render context
77 * @param {LibraryContext<T>} libraryContext context
78 * @returns {Source} source with library export
79 */
80 render(
81 source,
82 { chunkGraph, chunk, runtimeTemplate },
83 { options, compilation }
84 ) {
85 const modern = runtimeTemplate.supportsArrowFunction();
86 const modules = chunkGraph
87 .getChunkModules(chunk)
88 .filter(m => m instanceof ExternalModule);
89 const externals = /** @type {ExternalModule[]} */ (modules);
90 const externalsDepsArray = JSON.stringify(
91 externals.map(m =>
92 typeof m.request === "object" && !Array.isArray(m.request)
93 ? m.request.amd
94 : m.request
95 )
96 );
97 const externalsArguments = externals
98 .map(
99 m =>
100 `__WEBPACK_EXTERNAL_MODULE_${Template.toIdentifier(
101 `${chunkGraph.getModuleId(m)}`
102 )}__`
103 )
104 .join(", ");
105
106 const iife = runtimeTemplate.isIIFE();
107 const fnStart =
108 (modern
109 ? `(${externalsArguments}) => {`
110 : `function(${externalsArguments}) {`) +
111 (iife || !chunk.hasRuntime() ? " return " : "\n");
112 const fnEnd = iife ? ";\n}" : "\n}";
113
114 if (this.requireAsWrapper) {
115 return new ConcatSource(
116 `require(${externalsDepsArray}, ${fnStart}`,
117 source,
118 `${fnEnd});`
119 );
120 } else if (options.name) {
121 const name = compilation.getPath(options.name, {
122 chunk
123 });
124
125 return new ConcatSource(
126 `define(${JSON.stringify(name)}, ${externalsDepsArray}, ${fnStart}`,
127 source,
128 `${fnEnd});`
129 );
130 } else if (externalsArguments) {
131 return new ConcatSource(
132 `define(${externalsDepsArray}, ${fnStart}`,
133 source,
134 `${fnEnd});`
135 );
136 } else {
137 return new ConcatSource(`define(${fnStart}`, source, `${fnEnd});`);
138 }
139 }
140
141 /**
142 * @param {Chunk} chunk the chunk
143 * @param {Hash} hash hash
144 * @param {ChunkHashContext} chunkHashContext chunk hash context
145 * @param {LibraryContext<T>} libraryContext context
146 * @returns {void}
147 */
148 chunkHash(chunk, hash, chunkHashContext, { options, compilation }) {
149 hash.update("AmdLibraryPlugin");
150 if (this.requireAsWrapper) {
151 hash.update("requireAsWrapper");
152 } else if (options.name) {
153 hash.update("named");
154 const name = compilation.getPath(options.name, {
155 chunk
156 });
157 hash.update(name);
158 }
159 }
160}
161
162module.exports = AmdLibraryPlugin;