-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwebpackModded.js
196 lines (182 loc) · 6.62 KB
/
webpackModded.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
/*************************************************************
*
* Copyright (c) 2018 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Creates configurations for webpacking of MathJax components
*
* @author [email protected] (Davide Cervone)
*/
const fs = require('fs');
const path = require('path');
const webpack = require('webpack');
const TerserPlugin = require('terser-webpack-plugin');
/**************************************************************/
/**
* @param {string} string The string whose special characters are to be escaped
* @return {string} The string with regex special characters escaped
*/
function quoteRE(string) {
return string.replace(/([\\.{}[\]()?*^$])/g, '\\$1')
}
/**
* Creates the plugin needed for including jsdir in the output
*
* @param {string} js The location of the compiled js files
* @param {string} dir The directory of the component being built
* @return {any[]} The plugin array (empty or with the conversion plugin)
*/
const PLUGINS = function (js, dir) {
const mjdir = path.resolve(__dirname, '..', 'js');
const jsdir = path.resolve(dir, js);
//
// Record the js directory for the pack command
//
return [new webpack.DefinePlugin({
__JSDIR__: jsdir
})];
};
/**
* Creates the plugin needed for converting mathjax references to component/lib references
*
* @param {string} js The location of the compiled js files
* @param {string[]} lib The component library directories to be linked against
* @param {string} dir The directory of the component being built
* @return {any[]} The plugin array (empty or with the conversion plugin)
*/
const RESOLVE = function (js, libs, dir) {
const mjdir = path.resolve(__dirname, '..', 'js');
const jsdir = path.resolve(dir, js);
const mjRE = new RegExp('^(?:' + quoteRE(jsdir) + '|' + quoteRE(mjdir) + ')' + quoteRE(path.sep));
const root = path.dirname(mjdir);
//
// Add directory names to libraries
//
libs = libs.map(lib => path.join(lib.charAt(0) === '.' ? dir : root, lib) + path.sep);
//
// Function replace imported files by ones in the specified component lib directories.
//
const replaceLibs = (resource) => {
//
// The full file name to check.
//
const request = require.resolve(
resource.request ?
resource.request.charAt(0) === '.' ? path.resolve(resource.path, resource.request) : resource.request :
resource.path
);
//
// Only check files in the MathJax js directory.
//
if (!request.match(mjRE)) return;
//
// Loop through the libraries and see if the imported file is there.
// If so, replace the request with the library version and return.
//
for (const lib of libs) {
const file = request.replace(mjRE, lib);
if (fs.existsSync(file)) {
resource.path = file;
resource.request = undefined;
return;
}
}
}
//
// A plugin that looks for files and modules to see if they need replacing with library versions.
//
class ResolveReplacementPlugin {
apply(compiler) {
compiler.hooks.file.tap(ResolveReplacementPlugin.name, replaceLibs);
compiler.hooks.module.tap(ResolveReplacementPlugin.name, replaceLibs);
}
}
return { plugins: [new ResolveReplacementPlugin()] };
}
/**
* Add babel-loader to appropriate directories
*
* @param {string} dir The directory for the component being built
* @return {any} The modules specification for the webpack configuration
*/
const MODULE = function (dir) {
//
// Only need to transpile our directory and components directory
//
const dirRE = (dir.substr(0, __dirname.length) === __dirname ? quoteRE(__dirname) :
'(?:' + quoteRE(__dirname) + '|' + quoteRE(dir) + ')');
return {
// NOTE: for babel transpilation
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/
},
{
test: new RegExp(dirRE + quoteRE(path.sep) + '.*\\.js$'),
exclude: new RegExp(quoteRE(path.join(path.dirname(__dirname), 'es5') + path.sep)),
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/env']
}
}
}]
}
};
/**
* Create a webpack configuration for a distribution file
*
* @param {string} name The name of the component to create
* @param {string} js The path to the compiled .js files
* @param {string[]} libs Array of paths to component lib directories to link against
* @param {string} dir The directory of the component buing built
* @param {string} dist The path to the directory where the component .js file will be placed
* (defaults to es5 in the same directory as the js directory)
*/
const PACKAGE = function (name, js, libs, dir, dist) {
const distDir = dist ? path.resolve(dir, dist) :
path.resolve(path.dirname(js), 'es5', path.dirname(name));
name = path.basename(name);
return {
name: name,
entry: path.join(dir, name + '.js'),
output: {
path: distDir,
filename: name + (dist === '.' ? '.min.js' : '.js')
},
target: ['web', 'es5'], // needed for IE11 and old browsers
plugins: PLUGINS(js, dir),
resolve: RESOLVE(js, libs, dir),
module: MODULE(dir),
performance: {
hints: false
},
optimization: {
minimize: true,
minimizer: [new TerserPlugin({
extractComments: false,
terserOptions: {
output: {
ascii_only: true
}
}
})]
},
mode: 'production'
};
}
module.exports = PACKAGE;