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

Improve build process #1205

Merged
merged 2 commits into from
Nov 1, 2021
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
219 changes: 155 additions & 64 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,35 +21,46 @@ module.exports = (grunt) => {
const BANNER =
`VexFlow ${packageJSON.version} ${new Date().toISOString()} ${GIT_COMMIT_HASH}\n` +
`Copyright (c) 2010 Mohit Muthanna Cheppudira <mohit@muthanna.com>\n` +
`http://www.vexflow.com http://github.com/0xfe/vexflow`;
`https://www.vexflow.com https://github.com/0xfe/vexflow`;

// Used for eslint
const SOURCES = ['./src/*.ts', './src/*.js'];

function webpackConfig(target, chunkFilename, configFile, moduleEntry, mode, libraryName) {
// Switching the mode from 'development' => 'production' will enable minification, etc.
// See: https://webpack.js.org/configuration/mode/
function webpackConfig(outputFile, chunkFilename, tsconfig, moduleEntry, mode) {
// Support different ways of loading VexFlow.
// The `globalObject` string is assigned to `root` in line 15 of vexflow-debug.js.
// VexFlow is exported as root["Vex"], and can be accessed via:
// - `window.Vex` in browsers
// - `globalThis.Vex` in node JS >= 12
// - `this.Vex` in all other environments
// See: https://webpack.js.org/configuration/output/#outputglobalobject
let globalObject = `typeof window !== 'undefined' ? window : typeof globalThis !== 'undefined' ? globalThis : this`;
// However, the globalObject approach currently breaks the lazy loading of fonts.
// Unset the globalObject if we are doing lazy loading with webpack.
if (chunkFilename !== undefined) {
globalObject = undefined;
}

return {
mode: mode,
entry: moduleEntry,
output: {
path: BUILD_DIR,
filename: target,
filename: outputFile,
chunkFilename: chunkFilename,
library: libraryName,
libraryTarget: 'umd',
libraryExport: 'default',
// Support different ways of loading VexFlow.
// The `globalObject` string is assigned to `root` in line 15 of vexflow-debug.js.
// VexFlow is exported as root["Vex"], and can be accessed via:
// - `window.Vex` in browsers
// - `globalThis.Vex` in node JS >= 12
// - `this.Vex` in all other environments
// See: https://webpack.js.org/configuration/output/#outputglobalobject
globalObject: `typeof window !== 'undefined' ? window : typeof globalThis !== 'undefined' ? globalThis : this`,
library: {
name: 'Vex',
type: 'umd',
export: 'default',
},
globalObject: globalObject,
publicPath: 'auto',
},
resolve: {
extensions: ['.ts', '.js', '.json'],
plugins: [new TsconfigPathsPlugin({ configFile: configFile })],
plugins: [new TsconfigPathsPlugin({ configFile: tsconfig })],
},
devtool: process.env.VEX_GENMAP || mode === 'production' ? 'source-map' : false,
module: {
Expand All @@ -61,7 +72,7 @@ module.exports = (grunt) => {
{
loader: 'ts-loader',
options: {
configFile: configFile,
configFile: tsconfig,
},
},
],
Expand All @@ -88,72 +99,109 @@ module.exports = (grunt) => {
}

const webpackProdStatic = webpackConfig(
'vexflow-full-min.js',
'vexflow-[name]-min.js',
'vexflow.js',
undefined /* chunkFileName */,
'tsconfig.json',
MODULE_ENTRY_SRC,
'production',
'Vex'
'production'
);
const webpackProdDynamic = webpackConfig(
'vexflow-core-min.js',
'vexflow-font-[name]-min.js',
'vexflow-core.js',
'vexflow-font-[name].js',
'tsconfig.dynamic.json',
MODULE_ENTRY_SRC,
'production',
'Vex'
'production'
);
const webpackDevStatic = webpackConfig(
'vexflow.js',
undefined /* chunkFileName */,
'tsconfig.json',
MODULE_ENTRY_SRC,
'development'
);
const webpackDevDynamic = webpackConfig(
'vexflow-core.js',
'vexflow-font-[name].js',
'tsconfig.dynamic.json',
MODULE_ENTRY_SRC,
'development'
);
const webpackDev = webpackConfig(
'vexflow-debug.js',
'vexflow-[name]-debug.js',
undefined /* chunkFileName */,
'tsconfig.json',
MODULE_ENTRY_SRC,
'development',
'Vex'
'development'
);
const webpackTest = webpackConfig(
'vexflow-tests.js',
'vexflow-[name]-test.js',
undefined /* chunkFileName */,
'tsconfig.json',
MODULE_ENTRY_TESTS,
'development',
'Vex' /* Previously VFTests. TODO: Remove this! */
'development'
);

const watchOptions = {
watch: true,
keepalive: true,
ignored: /node_modules/,
};

grunt.initConfig({
pkg: packageJSON,
webpack: {
buildStatic: webpackProdStatic,
buildDynamic: webpackProdDynamic,
buildDev: webpackDev,
buildTest: webpackTest,
buildStatic: webpackProdStatic,
buildDynamic: webpackProdDynamic,
watchDev: {
...webpackDev,
watch: true,
keepalive: true,
failOnError: false,
...watchOptions,
},
watchTest: {
...webpackTest,
watch: true,
keepalive: true,
failOnError: false,
...watchOptions,
},
watchStatic: {
...webpackDevStatic,
...watchOptions,
},
watchDynamic: {
...webpackDevDynamic,
...watchOptions,
},
},
concurrent: {
options: {
logConcurrentOutput: true,
indent: false,
},
tasks: ['webpack:watchDev', 'webpack:watchTest'],
dev: ['webpack:watchDev', 'webpack:watchTest'],
static: ['webpack:watchStatic'],
dynamic: ['webpack:watchDynamic'],
staticAndDynamic: ['webpack:watchStatic', 'webpack:watchDynamic'],
},
eslint: {
target: SOURCES.concat('./tests'),
options: { fix: true },
},
qunit: {
files: ['tests/flow.html'],
files: ['tests/flow-headless-browser.html'],
},
copy: {
// copy the vexflow.js production build to vexflow.module.js
module: {
src: path.join(BUILD_DIR, 'vexflow.js'),
dest: path.join(BUILD_DIR, 'vexflow.module.js'),
options: {
process: function (content, srcpath) {
// Insert the export line BEFORE the source map comment.
const srcMapLinePrefix = '//# sourceMappingURL';
const exportVex = 'export default Vex;\n';
return content.replace(srcMapLinePrefix, exportVex + srcMapLinePrefix);
},
},
},
release: {
files: [
{
Expand Down Expand Up @@ -229,40 +277,83 @@ module.exports = (grunt) => {
grunt.loadNpmTasks('grunt-eslint');
grunt.loadNpmTasks('grunt-webpack');
grunt.loadNpmTasks('grunt-concurrent');
grunt.loadNpmTasks('grunt-force-task');

// Default tasks that run when you type `grunt`.
grunt.registerTask('default', [
'clean',
'eslint',
'webpack:buildStatic',
'webpack:buildDynamic',
'webpack:buildDev',
'webpack:buildTest',
'typedoc',
]);
grunt.registerTask(
'default',
'Build VexFlow', //
[
'clean',
'eslint',
'webpack:buildDev',
'webpack:buildTest',
'webpack:buildStatic',
'webpack:buildDynamic',
'copy:module',
'typedoc',
]
);

grunt.registerTask('watch', 'Watch src/ and tests/ concurrently', ['clean', 'eslint', 'concurrent']);
// `grunt watch`
grunt.registerTask(
'watch',
'Watch src/ & tests/ for changes. Generate dev builds.', //
['clean', 'force:eslint', 'concurrent:dev']
);

grunt.registerTask('test', 'Run qunit tests.', ['clean', 'webpack:buildDev', 'webpack:buildTest', 'qunit']);
// `grunt watch:static`
grunt.registerTask(
'watch:static',
'Watch src/ for changes. Generate dev builds for pre-loaded fonts.', //
['clean', 'force:eslint', 'concurrent:static']
);

// Release current build.
grunt.registerTask('stage', 'Stage current bundles to releases/.', () => {
grunt.task.run('default');
grunt.task.run('qunit');
grunt.task.run('copy:release');
});
// `grunt watch:dynamic`
grunt.registerTask(
'watch:dynamic',
'Watch src/ for changes. Generate dev builds for dynamically loaded fonts.', //
['clean', 'force:eslint', 'concurrent:dynamic']
);

// `grunt watch:staticAndDynamic`
grunt.registerTask(
'watch:staticAndDynamic',
'Watch src/ for changes.', //
['clean', 'force:eslint', 'concurrent:staticAndDynamic']
);

// `grunt test`
grunt.registerTask(
'test',
'Run qunit tests.', //
['clean', 'webpack:buildDev', 'webpack:buildTest', 'qunit']
);

// `grunt reference` will build the current HEAD revision and copy it to reference/
// After developing new features or fixing a bug, you can compare the current working tree
// against the reference with: `npm run test:reference`. See package.json for details.
grunt.registerTask(
'reference',
'Build to reference/.', //
['default', 'qunit', 'copy:reference']
);

// Release current build.
grunt.registerTask('reference', 'Stage current bundles to reference/.', () => {
grunt.task.run('default');
grunt.task.run('qunit');
grunt.task.run('copy:reference');
});
grunt.registerTask(
'stage',
'Build to releases/.', //
['default', 'qunit', 'copy:release']
);

grunt.registerTask('alldone', 'Publish VexFlow NPM.', () => {
grunt.log.ok('NOT YET DONE: Run `npm publish` now to publish NPM.');
});

// Increment package version generate releases
grunt.registerTask('publish', 'Generate releases.', ['bump', 'stage', 'gitcommit:releases', 'release', 'alldone']);
// Increment package version and generate releases. Does NOT automatically publish to NPM.
grunt.registerTask(
'publish',
'Generate releases.', //
['bump', 'stage', 'gitcommit:releases', 'release', 'alldone']
);
};
17 changes: 17 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@
"name": "vexflow",
"version": "3.0.9",
"description": "A JavaScript library for rendering music notation and guitar tablature",
"main": "src/index.ts",
"browser": "build/vexflow.js",
"main": "build/vexflow.js",
"repository": {
"type": "git",
"url": "https://github.com/0xfe/vexflow.git"
},
"author": {
"name": "Mohit Muthanna Cheppudira",
"email": "mohit@muthanna.com",
"url": "http://muthanna.com"
"url": "https://muthanna.com/"
},
"license": "MIT",
"bugs": {
Expand All @@ -37,6 +38,7 @@
"grunt-contrib-qunit": "^5.1.1",
"grunt-contrib-watch": "^1.1.0",
"grunt-eslint": "^24.0.0",
"grunt-force-task": "^3.0.0",
"grunt-git": "^1.1.1",
"grunt-release": "^0.14.0",
"grunt-typedoc": "^0.2.4",
Expand Down Expand Up @@ -70,7 +72,7 @@
"cache:restore:reference": "if [ -d ./reference/images ]; then mv ./reference/images ./build/images/reference; else npm run generate:reference; fi;",
"test:reference:cache": "npm run cache:save:reference && npm run lint && npm run qunit && npm run generate:current && npm run cache:restore:reference && npm run diff:reference"
},
"homepage": "http://vexflow.com",
"homepage": "https://vexflow.com/",
"keywords": [
"music",
"notation",
Expand Down
Loading