diff --git a/.gitignore b/.gitignore index 183f803..a79243f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ /.idea /packages/pegjs/dist /examples/*.js -/node_modules +node_modules /coverage /.nyc_output /website/js/*-bundle.js diff --git a/package.json b/package.json index 9956882..26eaf92 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "spec": "mocha --recursive", "benchmark": "benchmark", "build-parser": "pegjs -c src/pegjs.config.js", - "generate-dist": "rollup -c", + "generate-dist": "bundle", "clean": "rimraf packages/pegjs/dist website/js/*-bundle.js examples/*.js", "impact": "impact master", "start": "node server.js", @@ -27,14 +27,7 @@ "express": "4.16.4", "express-layout": "0.1.0", "morgan": "1.9.1", - "pretty-ms": "4.0.0", - "sinon": "7.1.0", - "rollup": "0.66.6", - "rollup-plugin-babel": "4.0.3", - "rollup-plugin-commonjs": "9.2.0", - "rollup-plugin-multi-entry": "2.0.2", - "rollup-plugin-node-resolve": "3.4.0", - "rollup-plugin-json": "3.1.0" + "sinon": "7.1.0" }, "devDependencies": { "coveralls": "3.0.2", @@ -43,8 +36,7 @@ "eslint": "5", "eslint-config-futagozaryuu": "5", "mocha": "5.2.0", - "nyc": "13.1.0", - "rollup-plugin-terser": "3.0.0" + "nyc": "13.1.0" }, "engines": { "node": ">= 6" diff --git a/rollup.config.js b/rollup.config.js deleted file mode 100644 index d8b0f66..0000000 --- a/rollup.config.js +++ /dev/null @@ -1,69 +0,0 @@ -"use strict"; - -const dedent = require( "dedent" ); -const babel = require( "rollup-plugin-babel" ); -const commonjs = require( "rollup-plugin-commonjs" ); -const json = require( "rollup-plugin-json" ); -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 ), - json( { namedExports: false } ), - 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 3a18a06..cd22850 100644 --- a/server.js +++ b/server.js @@ -1,25 +1,14 @@ "use strict"; const bodyParser = require( "body-parser" ); +const bundle = require( "bundle" ); const express = require( "express" ); const layout = require( "express-layout" ); const logger = require( "morgan" ); const { readFileSync } = require( "fs" ); 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 json = require( "rollup-plugin-json" ); -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( process.cwd(), "" ) - .replace( /\\/g, "/" ) - .replace( /^\//, "" ); /* Setup */ @@ -127,132 +116,24 @@ app.get( "/development/benchmark", ( req, res ) => { /* Bundle local sources (and watch for changes on non-production NODE_ENV) */ -const babelOptions = require( "./.babelrc" ); -babelOptions.babelrc = false; -babelOptions.exclude = "node_modules/**"; -babelOptions.runtimeHelpers = true; - [ { name: "benchmark", input: "tools/benchmark/browser.js" }, { name: "peg", input: "packages/pegjs/lib/peg.js", format: "umd" }, { name: "test", input: "test/**/*.js" }, -].forEach( bundle => { - - const plugins = [ - resolve(), - commonjs(), - json( { namedExports: false } ), - babel( babelOptions ), - ]; - - if ( bundle.input.includes( "*" ) ) plugins.unshift( multiEntry() ); - - const config = { - - input: bundle.input, - output: { - file: `website/js/${ bundle.name }-bundle.js`, - format: bundle.format || "iife", - name: bundle.name, - }, - plugins, - onwarn( warning, warn ) { - - if ( WARNINGS ) warn( warning ); - - }, - - }; - - // 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" ) { +].forEach( project => { - const output = config.output; + bundle( { - rollup - .rollup( config ) - .then( bundle => { - - console.info( `pegjs-website > bundling ${ pp( config.input ) }` ); - return bundle.write( output ); - - } ) - .then( () => { - - console.info( `pegjs-website > created ${ pp( output.file ) }` ); - - } ) - .catch( handleError ); - - return void 0; - - } - - const watcher = rollup.watch( { - - ...config, - watch: { - include: [ - "packages/**", - "test/**", - "tools/benchmark/**" - ], - }, - - } ); - - // 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; - - } + format: project.format, + name: project.name, + source: project.input, + target: `website/js/${ project.name }-bundle.js`, + silent: !! WARNINGS, + watch: NODE_ENV !== "production", } ); - process.on( "exit", () => watcher.close() ); - } ); /* Main */ diff --git a/.babelrc.js b/tools/bundle/babelOptions.js similarity index 57% rename from .babelrc.js rename to tools/bundle/babelOptions.js index 41a0792..79bf904 100644 --- a/.babelrc.js +++ b/tools/bundle/babelOptions.js @@ -1,6 +1,7 @@ "use strict"; -module.exports = { +// @babel/core +const babelOptions = { "comments": false, "compact": false, "presets": [ @@ -15,3 +16,10 @@ module.exports = { ] ] }; + +// rollup-plugin-babel +babelOptions.babelrc = false; +babelOptions.exclude = "node_modules/**"; +babelOptions.runtimeHelpers = true; + +module.exports = babelOptions; diff --git a/tools/bundle/create-pegjs-dist.js b/tools/bundle/create-pegjs-dist.js new file mode 100644 index 0000000..2e12a60 --- /dev/null +++ b/tools/bundle/create-pegjs-dist.js @@ -0,0 +1,44 @@ +#!/usr/bin/env node + +"use strict"; + +const bundle = require( "./index" ); +const dedent = require( "dedent" ); +const peg = require( "pegjs" ); + +const HEADER = dedent` + + /** + * PEG.js v${ peg.VERSION } + * https://pegjs.org/ + * + * Copyright (c) 2010-2016 David Majda + * Copyright (c) 2017+ Futago-za Ryuu + * + * Released under the MIT License. + */ + + /* eslint-disable */ + +`; + +function generate( target ) { + + bundle( { + + banner: HEADER, + format: "umd", + name: "peg", + source: "packages/pegjs/lib/peg.js", + target: `packages/pegjs/dist/${ target }`, + silent: process.argv.includes( "-s" ), + + } ); + +} + +// es5 release +generate( "peg.js" ); + +// es5 release (minified) +generate( "peg.min.js" ); diff --git a/tools/bundle/index.js b/tools/bundle/index.js new file mode 100644 index 0000000..7f4ba3b --- /dev/null +++ b/tools/bundle/index.js @@ -0,0 +1,139 @@ +"use strict"; + +const babelOptions = require( "./babelOptions" ); +const ms = require( "pretty-ms" ); +const rollup = require( "rollup" ); +const babel = require( "rollup-plugin-babel" ); +const commonjs = require( "rollup-plugin-commonjs" ); +const json = require( "rollup-plugin-json" ); +const multiEntry = require( "rollup-plugin-multi-entry" ); +const resolve = require( "rollup-plugin-node-resolve" ); +const { terser } = require( "rollup-plugin-terser" ); + +// pretty-path +function pp( p ) { + + return ( Array.isArray( p ) ? p.join( ", " ) : p ) + .replace( process.cwd(), "" ) + .replace( /\\/g, "/" ) + .replace( /^\//, "" ); + +} + +// 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 ); + +} + +module.exports = bundle => { + + const log = bundle.silent === true ? () => void 0 : console.info; + + const plugins = [ + resolve(), + commonjs(), + json( { namedExports: false } ), + babel( babelOptions ), + ]; + + if ( bundle.source.includes( "*" ) ) plugins.unshift( multiEntry() ); + + if ( bundle.target.endsWith( ".min.js" ) ) + + plugins.push( terser( { output: { comments: /MIT License/ } } ) ); + + const config = { + + input: bundle.source, + output: { + banner: bundle.banner, + file: bundle.target, + format: bundle.format || "iife", + interop: false, + name: bundle.name, + }, + plugins, + onwarn( warning, warn ) { + + if ( warning.code === "CIRCULAR_DEPENDENCY" ) return void 0; + if ( warning.code === "NAMESPACE_CONFLICT" ) return void 0; + if ( warning.code === "EVAL" ) return void 0; + + if ( bundle.silent !== true ) warn( warning ); + + }, + treeshake: { + propertyReadSideEffects: true, + }, + watch: { + exclude: "node_modules/**", + }, + + }; + + if ( bundle.watch !== true ) { + + log( `@pegjs/bundle > bundling ${ pp( config.input ) }` ); + + return rollup.rollup( config ) + .then( bundle => bundle.write( config.output ) ) + .then( () => { + + log( `@pegjs/bundle > created ${ pp( bundle.target ) }` ); + + } ) + .catch( handleError ); + + } + + const watcher = rollup.watch( config ); + + // https://rollupjs.org/guide/en#rollup-watch + watcher.on( "event", event => { + + switch ( event.code ) { + + case "BUNDLE_START": + log( `@pegjs/bundle > watching ${ pp( event.input ) }` ); + break; + + case "BUNDLE_END": + log( `@pegjs/bundle > created ${ pp( event.output ) } in ${ ms( event.duration ) }` ); + break; + + case "ERROR": + handleError( event.error ); + break; + + case "FATAL": + console.error( "@pegjs/bundle > Fatel Error!" ); + handleError( event.error ); + break; + + } + + } ); + + process.on( "exit", () => watcher.close() ); + return watcher; + +}; diff --git a/tools/bundle/package.json b/tools/bundle/package.json new file mode 100644 index 0000000..c74deea --- /dev/null +++ b/tools/bundle/package.json @@ -0,0 +1,18 @@ +{ + "name": "bundle", + "version": "2.1.0", + "private": true, + "main": "index.js", + "bin": "create-pegjs-dist.js", + "dependencies": { + "dedent": "0.7.0", + "pretty-ms": "4.0.0", + "rollup": "0.66.6", + "rollup-plugin-babel": "4.0.3", + "rollup-plugin-commonjs": "9.2.0", + "rollup-plugin-json": "3.1.0", + "rollup-plugin-multi-entry": "2.0.2", + "rollup-plugin-node-resolve": "3.4.0", + "rollup-plugin-terser": "3.0.0" + } +}