Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update build tools to work with extensions better #737

Merged
merged 2 commits into from
Feb 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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