From 30eea90614a2d1ddbdbbc645a508eb9f1cfbbc14 Mon Sep 17 00:00:00 2001 From: jos Date: Tue, 12 Jan 2016 11:38:38 +0100 Subject: [PATCH] Added build script for minimalist version --- HISTORY.md | 7 ++ gulpfile.js | 103 +++++++++++++++++++++++------- src/docs/which files do I need.md | 41 ++++++++++++ src/js/treemode.js | 14 +++- test/test_minimalist_min.html | 62 ++++++++++++++++++ 5 files changed, 203 insertions(+), 24 deletions(-) create mode 100644 src/docs/which files do I need.md create mode 100644 test/test_minimalist_min.html diff --git a/HISTORY.md b/HISTORY.md index 600f370..ecf375a 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -3,6 +3,13 @@ https://github.com/josdejong/jsoneditor +## not yet released, version 5.1.0 + +- Implemented support for JSON schema validation, powered by `ajv`. +- Added a minimalist bundle to the `dist` folder, excluding `ace` and `ajv`. +- Fixed an error throw when switching to mode "code" via the menu. + + ## 2015-12-31, version 5.0.1 - Fixed a bug in positioning of the context menu for multiple selected nodes. diff --git a/gulpfile.js b/gulpfile.js index d99713b..6c3713a 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -9,9 +9,11 @@ var webpack = require('webpack'); var uglify = require('uglify-js'); var NAME = 'jsoneditor'; +var NAME_MINIMALIST = 'jsoneditor-minimalist'; var ENTRY = './src/js/JSONEditor.js'; var HEADER = './src/js/header.js'; var IMAGE = './src/css/img/jsoneditor-icons.svg'; +var DOCS = './src/docs/*'; var DIST = './dist'; // generate banner with today's date and correct version @@ -29,7 +31,8 @@ var bannerPlugin = new webpack.BannerPlugin(createBanner(), { raw: true }); -var webpackConfig = { +// create a single instance of the compiler to allow caching +var compiler = webpack({ entry: ENTRY, output: { library: 'JSONEditor', @@ -39,17 +42,48 @@ var webpackConfig = { }, plugins: [ bannerPlugin ], cache: true -}; - -var uglifyConfig = { - outSourceMap: NAME + '.map', - output: { - comments: /@license/ - } -}; +}); // create a single instance of the compiler to allow caching -var compiler = webpack(webpackConfig); +var compilerMinimalist = webpack({ + entry: ENTRY, + output: { + library: 'JSONEditor', + libraryTarget: 'umd', + path: DIST, + filename: NAME_MINIMALIST + '.js' + }, + plugins: [ + bannerPlugin, + new webpack.IgnorePlugin(new RegExp('^brace')), + new webpack.IgnorePlugin(new RegExp('^ajv')) + ], + //exclude: [ + // 'brace', + // 'ajv/dist/ajv.bundle.js' + //], + + + cache: true +}); + +function minify(name) { + var result = uglify.minify([DIST + '/' + name + '.js'], { + outSourceMap: name + '.map', + output: { + comments: /@license/ + } + }); + + var fileMin = DIST + '/' + name + '.min.js'; + var fileMap = DIST + '/' + name + '.map'; + + fs.writeFileSync(fileMin, result.code); + fs.writeFileSync(fileMap, result.map); + + gutil.log('Minified ' + fileMin); + gutil.log('Mapped ' + fileMap); +} // make dist and dist/img folders gulp.task('mkdir', function () { @@ -73,6 +107,22 @@ gulp.task('bundle', ['mkdir'], function (done) { }); }); +// bundle minimalist version of javascript +gulp.task('bundle-minimalist', ['mkdir'], function (done) { + // update the banner contents (has a date in it which should stay up to date) + bannerPlugin.banner = createBanner(); + + compilerMinimalist.run(function (err, stats) { + if (err) { + gutil.log(err); + } + + gutil.log('bundled ' + NAME_MINIMALIST + '.js'); + + done(); + }); +}); + // bundle css gulp.task('bundle-css', ['mkdir'], function () { gulp.src([ @@ -98,18 +148,19 @@ gulp.task('copy-img', ['mkdir'], function () { gutil.log('Copied images'); }); +// create a folder img and copy the icons +gulp.task('copy-docs', ['mkdir'], function () { + gulp.src(DOCS) + .pipe(gulp.dest(DIST)); + gutil.log('Copied doc'); +}); + gulp.task('minify', ['bundle'], function () { - var result = uglify.minify([DIST + '/' + NAME + '.js'], uglifyConfig); - - var fileMin = DIST + '/' + NAME + '.min.js'; - var fileMap = DIST + '/' + NAME + '.map'; - - fs.writeFileSync(fileMin, result.code); - fs.writeFileSync(fileMap, result.map); - - gutil.log('Minified ' + fileMin); - gutil.log('Mapped ' + fileMap); + minify(NAME) +}); +gulp.task('minify-minimalist', ['bundle-minimalist'], function () { + minify(NAME_MINIMALIST) }); // TODO: zip file using archiver @@ -120,10 +171,18 @@ gulp.task('zip', shell.task([ // The watch task (to automatically rebuild when the source code changes) // Does only generate jsoneditor.js and jsoneditor.css, and copy the image -// Does NOT minify the code +// Does NOT minify the code and does NOT generate the minimalist version gulp.task('watch', ['bundle', 'bundle-css', 'copy-img'], function () { gulp.watch(['src/**/*'], ['bundle', 'bundle-css', 'copy-img']); }); // The default task (called when you run `gulp`) -gulp.task('default', ['bundle', 'bundle-css', 'copy-img', 'minify']); +gulp.task('default', [ + 'bundle', + 'bundle-minimalist', + 'bundle-css', + 'copy-img', + 'copy-docs', + 'minify', + 'minify-minimalist' +]); diff --git a/src/docs/which files do I need.md b/src/docs/which files do I need.md new file mode 100644 index 0000000..c987eff --- /dev/null +++ b/src/docs/which files do I need.md @@ -0,0 +1,41 @@ +# Which files do I need? + +Ehhh, that's quite some files in this dist folder. Which files do I need? + + +## Full version + +If you're not sure which version to use, use the full version. + +Which files are needed when using the full version? + +- jsoneditor.min.js +- jsoneditor.map (optional, for debugging purposes only) +- jsoneditor.min.css +- img/jsoneditor-icons.svg + + +## Minimalist version + +The minimalist version has excluded the following libraries: + +- `ace` (via `brace`), used for the code editor. +- `ajv`, used for JSON schema validation. + +This reduces the the size of the minified and gzipped JavaScript file from +about 160 kB to just 25 kB. + +When to use the minimalist version? + +- If you don't need the mode "code" and don't need JSON schema validation. +- Or if you want to provide `ace` and/or `ajv` yourself via the configuration + options, for example when you already use Ace in other parts of your + web application too and don't want to bundle the library twice. + +Which files are needed when using the minimalist version? + +- jsoneditor-minimalist.min.js +- jsoneditor-minimalist.map (optional, for debugging purposes only) +- jsoneditor.min.css +- img/jsoneditor-icons.svg + diff --git a/src/js/treemode.js b/src/js/treemode.js index 7ec12bb..37107b0 100644 --- a/src/js/treemode.js +++ b/src/js/treemode.js @@ -1,4 +1,10 @@ -var Ajv = require('ajv/dist/ajv.bundle.js'); +var Ajv; +try { + Ajv = require('ajv/dist/ajv.bundle.js'); +} +catch (err) { + // no problem... when we need Ajv we will throw a neat exception +} var Highlighter = require('./Highlighter'); var History = require('./History'); var SearchBox = require('./SearchBox'); @@ -601,7 +607,11 @@ treemode._createFrame = function () { // create one global event listener to handle all events from all nodes var editor = this; function onEvent(event) { - editor._onEvent(event); + // when switching to mode "code" or "text" via the menu, some events + // are still fired whilst the _onEvent methods is already removed. + if (editor._onEvent) { + editor._onEvent(event); + } } this.frame.onclick = function (event) { var target = event.target;// || event.srcElement; diff --git a/test/test_minimalist_min.html b/test/test_minimalist_min.html new file mode 100644 index 0000000..f6575a2 --- /dev/null +++ b/test/test_minimalist_min.html @@ -0,0 +1,62 @@ + + + + + + + + + + + + +

+ Switch editor mode using the mode box. + Note that the mode can be changed programmatically as well using the method + editor.setMode(mode), try it in the console of your browser. +

+ +
+ + + +