site/node_modules/mathjax-full/components/webpack.common.js

191 lines
6 KiB
JavaScript
Raw Normal View History

2024-10-14 06:09:33 +00:00
/*************************************************************
*
* 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 dpvc@mathjax.org (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: 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;