Skip to content

Commit

Permalink
Add flow-headless-browser.html to allow the qunit grunt task
Browse files Browse the repository at this point in the history
    to run a streamlined vexflow-tests.js. The full flow.html will
    include things like async loading of web fonts, etc.
Generate .d.ts files.
Gruntfile improvements to allow for dynamic font loading.
Delete jQuery file. Update glyphs.html to not require jQuery.
  • Loading branch information
ronyeh committed Nov 1, 2021
1 parent 646318c commit bdd4bbb
Show file tree
Hide file tree
Showing 13 changed files with 501 additions and 9,464 deletions.
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/,

This comment has been minimized.

Copy link
@tommadams

tommadams Nov 8, 2021

Contributor

This line is causing grunt watch to fail for me; commenting it out fixes the error.

The pertinent part of the error message is:

Warning: Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
 - configuration has an unknown property 'ignored'. These properties are valid:

Any ideas?

Here's the full error.

$ ./node_modules/.bin/grunt watch
Running "clean:0" (clean) task
>> 0 paths cleaned.

Running "force:eslint" (force) task

Running "force-internal:pre:eslint" (force-internal) task
>> Enable force mode for task eslint.

Running "eslint:target" (eslint) task

Running "force-internal:post:eslint" (force-internal) task
>> Reset force mode for task eslint.

Running "concurrent:dev" (concurrent) task
Running "webpack:watchDev" (webpack) task
Running "webpack:watchTest" (webpack) task
Warning: Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
 - configuration has an unknown property 'ignored'. These properties are valid:
   object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, externals?, externalsPresets?, externalsType?, ignoreWarnings?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? }
   -> Options object as provided by the user.
   For typos: please correct them.
   For loader options: webpack >= v2.0.0 no longer allows custom properties in configuration.
     Loaders should be updated to allow passing options via loader options in module.rules.
     Until loaders are updated one can use the LoaderOptionsPlugin to pass these options to the loader:
     plugins: [
       new webpack.LoaderOptionsPlugin({
         // test: /\.xxx$/, // may apply this only for some modules
         options: {
           ignored: …
         }
       })
     ] Use --force to continue.

Aborted due to warnings.
Warning: Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
 - configuration has an unknown property 'ignored'. These properties are valid:
   object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, externals?, externalsPresets?, externalsType?, ignoreWarnings?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? }
   -> Options object as provided by the user.
   For typos: please correct them.
   For loader options: webpack >= v2.0.0 no longer allows custom properties in configuration.
     Loaders should be updated to allow passing options via loader options in module.rules.
     Until loaders are updated one can use the LoaderOptionsPlugin to pass these options to the loader:
     plugins: [
       new webpack.LoaderOptionsPlugin({
         // test: /\.xxx$/, // may apply this only for some modules
         options: {
           ignored: …
         }
       })
     ] Use --force to continue.

Aborted due to warnings.
Warning:  Use --force to continue.

Aborted due to warnings.

This comment has been minimized.

Copy link
@ronyeh

ronyeh Nov 8, 2021

Author Collaborator

Thanks. In my current branch that line has changed already. It currently looks like this:

  const watch = {
    watch: true,
    watchOptions: {
      aggregateTimeout: 800 /* ms */,
      ignored: ['**/node_modules'],
    },
  };

But it's unclear we truly need the ignored field. I had read on stackoverflow it improves watch performance to ignore folders with too many files.

This comment has been minimized.

Copy link
@ronyeh

ronyeh Nov 8, 2021

Author Collaborator

Since this issue is in master, I can do a test to see if I can repro. If so, I can just remove that line for now.

Thanks for the bug report!

};

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

0 comments on commit bdd4bbb

Please sign in to comment.