Skip to content

Commit

Permalink
Merge pull request #737 from mathjax/build-tools
Browse files Browse the repository at this point in the history
Update build tools to work with extensions better
  • Loading branch information
dpvc committed Feb 22, 2022
2 parents 611a48c + fd90884 commit e3cd132
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 71 deletions.
27 changes: 13 additions & 14 deletions components/bin/build
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ const EXPORT_PROCESS = ['let', 'const', 'var', 'function', 'class', 'namespace']
/**
* The relative path to the MathJax directory
*/
const mjPath = path.relative(process.cwd(), path.resolve(__dirname,'../../js'));
const mjPath = path.relative(process.cwd(), path.resolve(__dirname, '..', '..', 'js'));
const mjGlobal = path.join('..', mjPath, 'components', 'global.js');

/**
* Read the configuration for the component
Expand All @@ -53,14 +54,14 @@ const config = JSON.parse(fs.readFileSync(process.argv[2] || 'build.json'));
/**
* Extract the configuration values
*/
const COMPONENT = path.basename(config.component || 'part'); // name of the component
const TARGETS = config.targets || []; // the files to include in the component
const EXCLUDE = new Map((config.exclude || []).map(name => [name, true])); // files to exclude from the component
const EXCLUDESUBDIRS = config.excludeSubdirs === 'true'; // exclude subdirectories
const MATHJAX = config.js || config.mathjax || mjPath; // path to the compiled .js files
const EXCLUDESUBDIRS = config.excludeSubdirs === 'true'; // exclude subdirectories or not
const JS = config.js || config.mathjax || mjPath; // path to the compiled .js files
const LIB = config.lib || './lib'; // path to the lib directory to create
const COMPONENT = path.basename(config.component || 'part'); // name of the component
const GLOBAL = config.global || `../${MATHJAX}/components/global.js`; // the location of global.js
const SRC = config.ts || MATHJAX.replace(/js$/, 'ts'); // path to the .ts files
const GLOBAL = config.global || mjGlobal; // path to the global.js file
const TS = config.ts || JS.replace(/js$/, 'ts'); // path to the .ts files

/**
* The list of files that need to be added to the lib directory
Expand Down Expand Up @@ -160,17 +161,15 @@ function processLines(file, objects) {
if (objects.length === 0) return [];
const dir = path.dirname(file).replace(/^\.$/, '');
const dots = dir.replace(/[^\/]+/g, '..') || '.';
const relative = path.join(dots, '..', MATHJAX, dir, path.basename(file)).replace(/\.ts$/, '.js');
const relative = path.join(dots, '..', JS, dir, path.basename(file)).replace(/\.ts$/, '.js');
const name = path.parse(file).name;
const lines = [
'"use strict";',
`Object.defineProperty(exports, '__esModule', {value: true});`
];
let source = (dir.replace(/\//g, '.') + '.' + name).replace(/^\./, '')
let source = ((dir.replace(/\//g, '.') + '.' + name).replace(/^\./, '')
+ (exists(path.resolve(JS, file.replace(/\.ts$/, ''))) ? '_ts' : ''))
.replace(/\.[^.]*/g, (x) => (x.substr(1).match(/[^a-zA-Z_]/) ? '[\'' + x.substr(1) + '\']' : x));
if (exists(path.resolve(MATHJAX, file.replace(/\.ts$/, '')))) {
source += '_ts';
}
for (const id of objects) {
lines.push(`exports.${id} = MathJax._.${source}.${id};`);
}
Expand Down Expand Up @@ -273,11 +272,11 @@ function processPackage(lines, space, dir) {
if (path.dirname(PACKAGE[0]) === dir) {
const file = PACKAGE.shift();
const name = path.basename(file);
const relativefile = path.join('..', MATHJAX, dir, name).replace(/\.ts$/, '.js');
const relativefile = path.join('..', JS, dir, name).replace(/\.ts$/, '.js');
const component = 'module' + (++importCount);
lines.push(`import * as ${component} from '${relativefile}';`);
let property = name.replace(/\.ts$/, '');
if (property !== name && exists(path.resolve(MATHJAX, file.replace(/\.ts$/, '')))) {
if (property !== name && exists(path.resolve(JS, file.replace(/\.ts$/, '')))) {
property += '_ts';
}
if (property.match(/[^a-zA-Z0-9_]/)) {
Expand Down Expand Up @@ -324,5 +323,5 @@ function rmDir(dir) {
//
rmDir(LIB);
console.info("Processing:");
processList(SRC, '', TARGETS);
processList(TS, '', TARGETS);
processGlobal();
16 changes: 14 additions & 2 deletions components/bin/makeAll
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,20 @@ const fs = require('fs');
const path = require('path');
const {execSync} = require('child_process');

const options = {
recursive: true
};

/**
* Get the directories to process
* Get the directories to process and check for options
*/
const dirs = process.argv.slice(2);

if (dirs[0] === '--no-subdirs') {
dirs.shift();
options.recursive = false;
}

if (dirs.length === 0) {
dirs.push('.');
}
Expand Down Expand Up @@ -74,7 +84,9 @@ function processList(dirs) {
*/
function processDir(dir, action) {
action(dir);
processSubdirs(dir, action);
if (options.recursive) {
processSubdirs(dir, action);
}
}

/**
Expand Down
30 changes: 20 additions & 10 deletions components/bin/pack
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ function fileSize(file) {
/**
* Regular expressions for the components directory and the MathJax .js location
*/
const compRE = fileRegExp(path.join(path.dirname(__dirname), 'src'));
const compRE = fileRegExp(path.dirname(__dirname));
const rootRE = fileRegExp(path.join(path.dirname(path.dirname(__dirname)), 'js'));
const nodeRE = fileRegExp(path.join(path.dirname(path.dirname(__dirname)), 'node_modules'));

Expand Down Expand Up @@ -83,7 +83,7 @@ async function webpackLib(dir) {
//
// Get js directory from the webpack.config.js file
//
const jsdir = require(path.resolve(dir, 'webpack.config.js')).plugins[0].definitions.jsdir;
const jsdir = require(path.resolve(dir, 'webpack.config.js')).plugins[0].definitions.__JSDIR__;
const jsRE = fileRegExp(jsdir);
const libRE = fileRegExp(path.resolve(jsdir, '..', 'components'));

Expand All @@ -103,17 +103,27 @@ async function webpackLib(dir) {
.replace(/ \+ \d+ modules/, '')
.replace(dirRE, '.');
}
for (const module of modules.sort((a,b) => a.name < b.name ? -1 : 1)) {
const list = [];
for (const module of modules) {
if (module.moduleType.match(/javascript/)) {
const name = module.name
.replace(compRE, '[components]')
.replace(rootRE, '[mathjax]')
.replace(nodeRE, '[node]')
.replace(jsRE, '[js]')
.replace(libRE, '[lib]');
console.log(' ' + name + fileSize(module));
let name = module.name
.replace(compRE, '[components]')
.replace(rootRE, '[mathjax]')
.replace(nodeRE, '[node]')
.replace(jsRE, '[js]')
.replace(libRE, '[lib]');
if (name.charAt(0) !== '.' && name.charAt(0) !== '[') {
name = path.relative(dir, name);
}
list.push(' ' + name + fileSize(module));
}
}
console.log(
list
.filter(a => a.slice(2, 4) === './').sort()
.concat(list.filter(a => a.slice(2, 4) !== './').sort())
.join('\n')
);
} catch (err) {
console.error(err);
}
Expand Down
105 changes: 60 additions & 45 deletions components/webpack.common.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,23 @@ 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
*
Expand All @@ -44,62 +61,59 @@ function quoteRE(string) {
* @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, libs, dir) {
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);
const rootRE = new RegExp('^' + quoteRE(root + path.sep));
const nodeRE = new RegExp('^' + quoteRE(path.dirname(root) + path.sep));

//
// Record the js directory for the pack command
// Add directory names to libraries
//
const plugins = [new webpack.DefinePlugin({jsdir: jsdir})];
libs = libs.map(lib => path.join(lib.charAt(0) === '.' ? dir : root, lib) + path.sep);

if (libs.length) {
plugins.push(
//
// Move mathjax references to component libraries
//
new webpack.NormalModuleReplacementPlugin(
/^[^\/]/,
function (resource) {
const request = require.resolve(resource.request.charAt(0) === '.' ?
path.resolve(resource.context, resource.request) :
resource.request);
if (!request.match(mjRE)) return;
for (const lib of libs) {
const file = request.replace(mjRE, path.join(root, lib) + path.sep);
if (fs.existsSync(file)) {
resource.request = file;
break;
}
}
}
)
//
// 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
);
}
plugins.push(
//
// Check for packages that should be rerouted to node_modules
// Only check files in the MathJax js directory.
//
new webpack.NormalModuleReplacementPlugin(
/^[^\/]$/,
function (resource) {
const request = require.resolve(resource.request.charAt(0) === '.' ?
path.resolve(resource.context, resource.request) :
resource.request);
if (request.match(rootRE) || !request.match(nodeRE) || fs.existsSync(request)) return;
const file = request.replace(nodeRE, path.join(root, 'node_modules') + path.sep);
if (fs.existsSync(file)) {
resource.request = file;
}
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;
}
)
);
return plugins;
};
}
}

//
// 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
Expand Down Expand Up @@ -150,7 +164,8 @@ const PACKAGE = function (name, js, libs, dir, dist) {
filename: name + (dist === '.' ? '.min.js' : '.js')
},
target: ['web', 'es5'], // needed for IE11 and old browsers
plugins: PLUGINS(js, libs, dir),
plugins: PLUGINS(js, dir),
resolve: RESOLVE(js, libs, dir),
module: MODULE(dir),
performance: {
hints: false
Expand Down

0 comments on commit e3cd132

Please sign in to comment.