diff --git a/.babelrc b/.babelrc.js
similarity index 87%
rename from .babelrc
rename to .babelrc.js
index d30817e..41a0792 100644
--- a/.babelrc
+++ b/.babelrc.js
@@ -1,4 +1,6 @@
-{
+"use strict";
+
+module.exports = {
"comments": false,
"compact": false,
"presets": [
@@ -12,4 +14,4 @@
}
]
]
-}
+};
diff --git a/.gitignore b/.gitignore
index 19cd755..183f803 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,5 +4,6 @@
/node_modules
/coverage
/.nyc_output
+/website/js/*-bundle.js
/*.log
/sh.exe.stackdump
diff --git a/gulpfile.js b/gulpfile.js
index 7855857..68d1b06 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -1,21 +1,9 @@
"use strict";
-const version = require( "./package" ).version;
-const spawn = require( "child_process" ).spawn;
-const dest = require( "gulp" ).dest;
-const src = require( "gulp" ).src;
-const series = require( "gulp" ).series;
-const task = require( "gulp" ).task;
+const { spawn } = require( "child_process" );
+const { series, src, task } = require( "gulp" );
const eslint = require( "gulp-eslint" );
const mocha = require( "gulp-mocha" );
-const dedent = require( "dedent" );
-const browserify = require( "browserify" );
-const babelify = require( "babelify" );
-const stream = require( "vinyl-source-stream" );
-const rename = require( "gulp-rename" );
-const buffer = require( "vinyl-buffer" );
-const uglify = require( "gulp-uglify" );
-const header = require( "gulp-header" );
const del = require( "del" );
const pump = require( "pump" );
@@ -43,6 +31,7 @@ task( "lint", () => pump(
"test/impact",
"test/spec/**/*.js",
"src/*.js",
+ "rollup.config.js",
"gulpfile.js",
"server.js",
] ),
@@ -74,54 +63,9 @@ task( "build:parser", cb => {
} );
-// Create the browser build.
-task( "build:browser", () => {
-
- const options = {
-
- bare: true,
- standalone: "peg",
- suffix: ".min",
-
- };
-
- const HEADER = dedent`
-
- /**
- * PEG.js v${ version }
- * https://pegjs.org/
- *
- * Copyright (c) 2010-2016 David Majda
- * Copyright (c) 2017+ Futago-za Ryuu
- *
- * Released under the MIT License.
- */
-
- /* eslint-disable */
-
- `;
-
- return pump(
-
- browserify( "packages/pegjs/lib/peg.js", options )
- .transform( babelify )
- .bundle(),
- stream( "peg.js" ),
- header( HEADER ),
- dest( "packages/pegjs/dist" ),
- rename( options ),
- buffer(),
- uglify(),
- header( HEADER ),
- dest( "browser" )
-
- );
-
-} );
-
// Delete the generated files.
task( "clean", () =>
- del( [ "browser", "examples/*.js" ] )
+ del( [ "packages/pegjs/dist", "website/js/*-bundle.js", "examples/*.js" ] )
);
// Default task.
diff --git a/package.json b/package.json
index 65d5362..431ef62 100644
--- a/package.json
+++ b/package.json
@@ -9,7 +9,7 @@
"spec": "gulp test",
"benchmark": "gulp benchmark",
"build:parser": "gulp build:parser",
- "build:browser": "gulp build:browser",
+ "build:dist": "rollup -c",
"clean": "gulp clean",
"start": "node server.js",
"test:impact": "node test/impact master",
@@ -19,9 +19,7 @@
"devDependencies": {
"@babel/core": "7.0.0",
"@babel/preset-env": "7.0.0",
- "babelify": "10.0.0",
"body-parser": "1.18.3",
- "browserify": "16.2.2",
"chai": "4.1.2",
"chai-like": "1.1.1",
"coveralls": "3.0.2",
@@ -34,16 +32,18 @@
"glob": "7.1.3",
"gulp": "4.0.0",
"gulp-eslint": "5.0.0",
- "gulp-header": "2.0.5",
"gulp-mocha": "6.0.0",
- "gulp-rename": "1.4.0",
- "gulp-uglify": "3.0.1",
"morgan": "1.9.0",
"nyc": "13.0.1",
+ "pretty-ms": "3.2.0",
"pump": "3.0.0",
"sinon": "6.2.0",
- "vinyl-buffer": "1.0.1",
- "vinyl-source-stream": "2.0.0"
+ "rollup": "0.65.2",
+ "rollup-plugin-babel": "4.0.3",
+ "rollup-plugin-commonjs": "9.1.6",
+ "rollup-plugin-multi-entry": "2.0.2",
+ "rollup-plugin-node-resolve": "3.4.0",
+ "rollup-plugin-terser": "2.0.2"
},
"engines": {
"node": ">= 6"
diff --git a/rollup.config.js b/rollup.config.js
new file mode 100644
index 0000000..78e3be0
--- /dev/null
+++ b/rollup.config.js
@@ -0,0 +1,67 @@
+"use strict";
+
+const dedent = require( "dedent" );
+const babel = require( "rollup-plugin-babel" );
+const commonjs = require( "rollup-plugin-commonjs" );
+const resolve = require( "rollup-plugin-node-resolve" );
+const { terser } = require( "rollup-plugin-terser" );
+
+const HEADER = dedent`
+
+ /**
+ * PEG.js v${ require( "pegjs" ).VERSION }
+ * https://pegjs.org/
+ *
+ * Copyright (c) 2010-2016 David Majda
+ * Copyright (c) 2017+ Futago-za Ryuu
+ *
+ * Released under the MIT License.
+ */
+
+ /* eslint-disable */
+
+`;
+
+const babelOptions = require( "./.babelrc" );
+babelOptions.babelrc = false;
+babelOptions.runtimeHelpers = true;
+
+function generate( target ) {
+
+ const config = {
+ input: "packages/pegjs/lib/peg.js",
+ output: {
+ file: `packages/pegjs/dist/${ target }`,
+ format: "umd",
+ name: "PEG",
+ banner: HEADER,
+ },
+ onwarn( warning, warn ) {
+
+ if ( warning.code !== "EVAL" ) warn( warning );
+
+ },
+ plugins: [
+ commonjs(),
+ babel( babelOptions ),
+ resolve(),
+ ],
+ };
+
+ if ( target.includes( ".min" ) )
+
+ config.plugins.push( terser( { output: { comments: /MIT License/ } } ) );
+
+ return config;
+
+}
+
+module.exports = [
+
+ // es5 release
+ generate( "peg.js" ),
+
+ // es5 release (minified)
+ generate( "peg.min.js" ),
+
+];
diff --git a/server.js b/server.js
index e8156c3..d06234c 100644
--- a/server.js
+++ b/server.js
@@ -1,19 +1,29 @@
"use strict";
-const babelify = require( "babelify" );
const bodyParser = require( "body-parser" );
-const browserify = require( "browserify" );
const express = require( "express" );
const layout = require( "express-layout" );
-const glob = require( "glob" ).sync;
const logger = require( "morgan" );
const { join } = require( "path" );
+const ms = require( "pretty-ms" );
+const rollup = require( "rollup" );
+const babel = require( "rollup-plugin-babel" );
+const commonjs = require( "rollup-plugin-commonjs" );
+const multiEntry = require( "rollup-plugin-multi-entry" );
+const resolve = require( "rollup-plugin-node-resolve" );
const path = ( ...parts ) => join( __dirname, ...parts );
+const pp = p => // pretty-path
+ ( Array.isArray( p ) ? p.join( ", " ) : p )
+ .replace( __dirname, "" )
+ .replace( /\\/g, "/" )
+ .replace( /^\//, "" );
/* Setup */
const app = express();
+const NODE_ENV = process.env.NODE_ENV;
+const WARNINGS = process.argv.includes( "--show-warnings" );
app.set( "views", path( "website", "views" ) );
app.set( "view engine", "ejs" );
@@ -91,12 +101,111 @@ app.get( "/benchmark", ( req, res ) => {
} );
-app.get( "/:dir/bundle.js", ( req, res ) => {
+/* Test: bundle and optionally watch */
- browserify( glob( `${ __dirname }/test/${ req.params.dir }/**/*.js` ) )
- .transform( babelify )
- .bundle()
- .pipe( res );
+const babelOptions = require( "./.babelrc" );
+babelOptions.babelrc = false;
+babelOptions.exclude = "node_modules/**";
+babelOptions.runtimeHelpers = true;
+
+[ "benchmark", "spec" ].forEach( testType => {
+
+ const bundleConfig = {
+
+ input: `test/${ testType }/**/*.js`,
+ output: {
+ name: `PEG_${ testType }`,
+ file: `website/js/${ testType }-bundle.js`,
+ format: "iife",
+ },
+ plugins: [
+ multiEntry(),
+ commonjs(),
+ babel( babelOptions ),
+ resolve(),
+ ],
+ onwarn( warning, warn ) {
+
+ if ( WARNINGS ) warn( warning );
+
+ },
+ treeshake: false,
+
+ };
+
+ // based on https://github.com/rollup/rollup/blob/master/bin/src/logging.ts
+ function handleError( err ) {
+
+ let description = err.message || err;
+
+ if ( err.name ) description = `${ err.name }: ${ description }`;
+
+ const message = err.plugin ? `(${ err.plugin } plugin) ${ description }` : description;
+
+ console.error( message.toString() );
+
+ if ( err.url ) console.error( err.url );
+
+ if ( err.loc )
+ console.error( `${ err.loc.file || err.id } (${ err.loc.line }:${ err.loc.column })` );
+ else if ( err.id )
+ console.error( err.id );
+
+ if ( err.frame ) console.error( err.frame );
+
+ if ( err.stack ) console.error( err.stack );
+
+ }
+
+ if ( NODE_ENV === "production" ) {
+
+ rollup
+ .rollup( bundleConfig )
+ .catch( handleError );
+
+ return void 0;
+
+ }
+
+ const watcher = rollup.watch( {
+
+ ...bundleConfig,
+ watch: {
+ include: [
+ "packages/**",
+ "test/**",
+ ],
+ },
+
+ } );
+
+ // https://rollupjs.org/guide/en#rollup-watch
+ watcher.on( "event", event => {
+
+ switch ( event.code ) {
+
+ case "BUNDLE_START":
+ console.info( `pegjs-website > bundling ${ pp( event.input ) }` );
+ break;
+
+ case "BUNDLE_END":
+ console.info( `pegjs-website > created ${ pp( event.output ) } in ${ ms( event.duration ) }` );
+ break;
+
+ case "ERROR":
+ handleError( event.error );
+ break;
+
+ case "FATAL":
+ console.error( "pegjs-website > Fatel Error!" );
+ handleError( event.error );
+ break;
+
+ }
+
+ } );
+
+ process.on( "exit", () => watcher.close() );
} );
diff --git a/website/views/benchmark.ejs b/website/views/benchmark.ejs
index f189ed7..53b9228 100644
--- a/website/views/benchmark.ejs
+++ b/website/views/benchmark.ejs
@@ -27,4 +27,4 @@
-
+
diff --git a/website/views/spec.ejs b/website/views/spec.ejs
index 4b7b46b..e60806c 100644
--- a/website/views/spec.ejs
+++ b/website/views/spec.ejs
@@ -9,7 +9,7 @@
} );
-
+