From 2e434f49f960c9f6bd8990fc3c080fce1ae5fbfe Mon Sep 17 00:00:00 2001 From: jos Date: Mon, 26 Dec 2016 10:18:26 +0100 Subject: [PATCH] Worked out react bundle (not yet working though) --- .gitignore | 1 + examples/10_react_component.html | 94 ------------ examples/react_demo/.gitignore | 15 ++ examples/react_demo/README.md | 3 + examples/react_demo/package.json | 18 +++ examples/react_demo/public/index.html | 12 ++ examples/react_demo/src/App.css | 0 examples/react_demo/src/App.js | 52 +++++++ examples/react_demo/src/index.css | 5 + examples/react_demo/src/index.js | 9 ++ gulpfile.js | 203 +++++++++++++++++--------- index.js | 1 + package.json | 3 +- react.js | 1 + src/components/JSONEditor.js | 1 - 15 files changed, 250 insertions(+), 168 deletions(-) delete mode 100644 examples/10_react_component.html create mode 100755 examples/react_demo/.gitignore create mode 100755 examples/react_demo/README.md create mode 100755 examples/react_demo/package.json create mode 100755 examples/react_demo/public/index.html create mode 100755 examples/react_demo/src/App.css create mode 100755 examples/react_demo/src/App.js create mode 100755 examples/react_demo/src/index.css create mode 100755 examples/react_demo/src/index.js create mode 100644 index.js create mode 100644 react.js diff --git a/.gitignore b/.gitignore index 6d062db..80f0af7 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,6 @@ dist downloads node_modules +flow-typed *.zip npm-debug.log diff --git a/examples/10_react_component.html b/examples/10_react_component.html deleted file mode 100644 index cafbebe..0000000 --- a/examples/10_react_component.html +++ /dev/null @@ -1,94 +0,0 @@ - - - - - React component | JSONEditor - - - - - - - -

- This demo shows how to load JSONEditor as a React Component -

- -
- - - - - - - - - - - - \ No newline at end of file diff --git a/examples/react_demo/.gitignore b/examples/react_demo/.gitignore new file mode 100755 index 0000000..6c96c5c --- /dev/null +++ b/examples/react_demo/.gitignore @@ -0,0 +1,15 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# dependencies +node_modules + +# testing +coverage + +# production +build + +# misc +.DS_Store +.env +npm-debug.log diff --git a/examples/react_demo/README.md b/examples/react_demo/README.md new file mode 100755 index 0000000..06d408c --- /dev/null +++ b/examples/react_demo/README.md @@ -0,0 +1,3 @@ +# JSONEditor React demo + +TODO: describe the demo diff --git a/examples/react_demo/package.json b/examples/react_demo/package.json new file mode 100755 index 0000000..bb18ccb --- /dev/null +++ b/examples/react_demo/package.json @@ -0,0 +1,18 @@ +{ + "name": "react_demo", + "version": "0.1.0", + "private": true, + "devDependencies": { + "react-scripts": "0.8.4" + }, + "dependencies": { + "react": "15.4.1", + "react-dom": "15.4.1" + }, + "scripts": { + "start": "react-scripts start", + "build": "react-scripts build", + "test": "react-scripts test --env=jsdom", + "eject": "react-scripts eject" + } +} diff --git a/examples/react_demo/public/index.html b/examples/react_demo/public/index.html new file mode 100755 index 0000000..9e2ed6e --- /dev/null +++ b/examples/react_demo/public/index.html @@ -0,0 +1,12 @@ + + + + + + + React demo | JSONeditor + + +
+ + diff --git a/examples/react_demo/src/App.css b/examples/react_demo/src/App.css new file mode 100755 index 0000000..e69de29 diff --git a/examples/react_demo/src/App.js b/examples/react_demo/src/App.js new file mode 100755 index 0000000..b500ef1 --- /dev/null +++ b/examples/react_demo/src/App.js @@ -0,0 +1,52 @@ +import React, { Component } from 'react' +import './App.css' + +// Load the react version of JSONEditor +// +// When installed via npm, import as: +// +// import JSONEditor from 'jsoneditor/react' +// +import JSONEditor from '../../../react' + + +const json = { + 'array': [1, 2, 3], + 'boolean': true, + 'null': null, + 'number': 123, + 'object': {'a': 'b', 'c': 'd'}, + 'string': 'Hello World' +} + +class App extends Component { + state = { + text: JSON.stringify(json) + } + + render() { + return ( +
+ +
+ ) + } + + onChange = (json) => { + console.log('onChange', json) + } + + onChangeText = (text) => { + console.log('onChangeText', text) + + this.setState({ text }) + } +} + +export default App diff --git a/examples/react_demo/src/index.css b/examples/react_demo/src/index.css new file mode 100755 index 0000000..b4cc725 --- /dev/null +++ b/examples/react_demo/src/index.css @@ -0,0 +1,5 @@ +body { + margin: 0; + padding: 0; + font-family: sans-serif; +} diff --git a/examples/react_demo/src/index.js b/examples/react_demo/src/index.js new file mode 100755 index 0000000..f66d1fc --- /dev/null +++ b/examples/react_demo/src/index.js @@ -0,0 +1,9 @@ +import React from 'react' +import ReactDOM from 'react-dom' +import App from './App' +import './index.css' + +ReactDOM.render( + , + document.getElementById('root') +) diff --git a/gulpfile.js b/gulpfile.js index 293c880..e50c7de 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,13 +1,14 @@ -var fs = require('fs') -var gulp = require('gulp') -var gutil = require('gulp-util') -var shell = require('gulp-shell') -var mkdirp = require('mkdirp') -var webpack = require('webpack') -var browserSync = require('browser-sync').create() +const fs = require('fs') +const gulp = require('gulp') +const gulpMultiProcess = require('gulp-multi-process') +const gutil = require('gulp-util') +const shell = require('gulp-shell') +const mkdirp = require('mkdirp') +const webpack = require('webpack') +const browserSync = require('browser-sync').create() -var WATCH = 'watch' -var WATCHING = process.argv[2] === WATCH +const WATCH = 'watch' +const WATCHING = process.argv[2] === WATCH if (WATCHING) { gutil.log('Watching src/*.') @@ -16,29 +17,44 @@ if (WATCHING) { gutil.log('Also, ./dist/minimalist code is not updated on changes.') } -var NAME = 'jsoneditor' -var NAME_MINIMALIST = 'jsoneditor-minimalist' -var ENTRY = './src/index.js' -var HEADER = './src/header.js' -var DIST = './dist' -var EMPTY = __dirname + '/src/utils/empty.js' +const NAME = 'jsoneditor.js' +const NAME_MINIMALIST = 'jsoneditor-minimalist.js' +const NAME_REACT = 'jsoneditor-react.js' +const NAME_REACT_MINIMALIST = 'jsoneditor-react-minimalist.js' +const ENTRY = './src/index.js' +const ENTRY_REACT = './src/components/JSONEditor.js' +const HEADER = './src/header.js' +const DIST = './dist' +const EMPTY = __dirname + '/src/utils/empty.js' // generate banner with today's date and correct version function createBanner() { - var today = gutil.date(new Date(), 'yyyy-mm-dd') // today, formatted as yyyy-mm-dd - var version = require('./package.json').version // math.js version + const today = gutil.date(new Date(), 'yyyy-mm-dd') // today, formatted as yyyy-mm-dd + const version = require('./package.json').version // math.js version return String(fs.readFileSync(HEADER)) .replace('@@date', today) .replace('@@version', version) } -var bannerPlugin = new webpack.BannerPlugin(createBanner(), { +const bannerPlugin = new webpack.BannerPlugin(createBanner(), { entryOnly: true, raw: true }) -var loaders = [ +const minifyPlugin = new webpack.optimize.UglifyJsPlugin() + +const excludeAcePlugin = new webpack.NormalModuleReplacementPlugin(new RegExp('/assets/ace$'), EMPTY) + +const excludeAjvPlugin = new webpack.NormalModuleReplacementPlugin(new RegExp('^ajv$'), EMPTY) + +const productionEnvPlugin = new webpack.DefinePlugin({ + 'process.env': { + NODE_ENV: JSON.stringify('production') + } +}) + +const loaders = [ { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader' }, { test: /\.json$/, loader: 'json' }, { test: /\.less$/, loaders: '!style!css!less!' }, @@ -46,61 +62,100 @@ var loaders = [ ] // create a single instance of the compiler to allow caching -var plugins = [ - bannerPlugin -] -if (!WATCHING) { - plugins.push(new webpack.optimize.UglifyJsPlugin()) - plugins.push(new webpack.DefinePlugin({ - 'process.env': { - NODE_ENV: JSON.stringify('production') - } - })) -} -var compiler = webpack({ +const compiler = webpack({ entry: ENTRY, devtool: 'source-map', debug: true, + cache: true, bail: true, output: { library: 'jsoneditor', libraryTarget: 'umd', path: DIST, - filename: NAME + '.js' + filename: NAME }, - plugins: plugins, + plugins: WATCHING + ? [bannerPlugin] + : [bannerPlugin, productionEnvPlugin, minifyPlugin], module: { - loaders: loaders - }, - cache: true + loaders + } }) // create a single instance of the compiler to allow caching -var compilerMinimalist = webpack({ +const compilerMinimalist = webpack({ entry: ENTRY, devtool: 'source-map', debug: true, + cache: true, output: { library: 'jsoneditor', libraryTarget: 'umd', path: DIST, - filename: NAME_MINIMALIST + '.js' + filename: NAME_MINIMALIST }, plugins: [ bannerPlugin, - new webpack.NormalModuleReplacementPlugin(new RegExp('/assets/ace$'), EMPTY), - new webpack.NormalModuleReplacementPlugin(new RegExp('^ajv$'), EMPTY), - new webpack.optimize.UglifyJsPlugin(), - new webpack.DefinePlugin({ - 'process.env': { - NODE_ENV: JSON.stringify('production') - } - }) + productionEnvPlugin, + excludeAcePlugin, + excludeAjvPlugin, + minifyPlugin ], module: { - loaders: loaders + loaders + } +}) + +const externals = { + 'react': 'commonjs react' +} + +// FIXME: get the react bundles working +// create a single instance of the compiler to allow caching +const compilerReact = webpack({ + entry: ENTRY_REACT, + devtool: 'source-map', + debug: true, + cache: true, + bail: true, + output: { + path: DIST, + filename: NAME_REACT }, - cache: true + plugins: [ + bannerPlugin, + productionEnvPlugin, + minifyPlugin + ], + module: { + loaders + }, + externals +}) + +// FIXME: get the react bundles working +// create a single instance of the compiler to allow caching +const compilerReactMinimalist = webpack({ + entry: ENTRY_REACT, + devtool: 'source-map', + debug: true, + cache: true, + bail: true, + output: { + path: DIST, + filename: NAME_REACT_MINIMALIST + }, + plugins: [ + bannerPlugin, + productionEnvPlugin, + excludeAcePlugin, + excludeAjvPlugin, + minifyPlugin + ], + module: { + loaders + }, + externals }) function handleCompilerCallback (err, stats) { @@ -116,41 +171,38 @@ function handleCompilerCallback (err, stats) { } } +function createBundleTask (compiler) { + return function (done) { + // update the banner contents (has a date in it which should stay up to date) + bannerPlugin.banner = createBanner() + + compiler.run(function (err, stats) { + handleCompilerCallback(err, stats) + + done() + }) + } +} + // make dist folder gulp.task('mkdir', function () { mkdirp.sync(DIST) }) // bundle javascript -gulp.task('bundle', ['mkdir'], function (done) { - // update the banner contents (has a date in it which should stay up to date) - bannerPlugin.banner = createBanner() - - compiler.run(function (err, stats) { - handleCompilerCallback(err, stats) - - gutil.log('bundled ' + NAME + '.js') - - done() - }) -}) +gulp.task('bundle', ['mkdir'], createBundleTask(compiler)) // 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() +gulp.task('bundle-minimalist', ['mkdir'], createBundleTask(compilerMinimalist)) - compilerMinimalist.run(function (err, stats) { - handleCompilerCallback(err, stats) +// bundle react version +gulp.task('bundle-react', ['mkdir'], createBundleTask(compilerReact)) - gutil.log('bundled ' + NAME_MINIMALIST + '.js') - - done() - }) -}) +// bundle react minimalist version +gulp.task('bundle-react-minimalist', ['mkdir'], createBundleTask(compilerReactMinimalist)) // TODO: zip file using archiver -var pkg = 'jsoneditor-' + require('./package.json').version + '.zip' +const pkg = 'jsoneditor-' + require('./package.json').version + '.zip' gulp.task('zip', shell.task([ 'zip ' + pkg + ' ' + 'README.md LICENSE HISTORY.md index.html src dist docs examples -r ' ])) @@ -177,4 +229,11 @@ gulp.task(WATCH, ['bundle'], function() { }) // The default task (called when you run `gulp`) -gulp.task('default', [ 'bundle', 'bundle-minimalist' ]) +gulp.task('default', function(done) { + return gulpMultiProcess([ + 'bundle', + 'bundle-minimalist', + 'bundle-react', + 'bundle-react-minimalist' + ], done); +}) diff --git a/index.js b/index.js new file mode 100644 index 0000000..af2df48 --- /dev/null +++ b/index.js @@ -0,0 +1 @@ +module.exports = require('./dist/jsoneditor') diff --git a/package.json b/package.json index 6346a9e..b2dfb09 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "jsoneditor", "version": "6.0.0-BETA", - "main": "./src/index", + "main": "./index.js", "description": "A web-based tool to view, edit, format, and validate JSON", "tags": [ "json", @@ -43,6 +43,7 @@ "flow-bin": "0.36.0", "graceful-fs": "4.1.11", "gulp": "3.9.1", + "gulp-multi-process": "0.1.0", "gulp-shell": "0.5.2", "gulp-util": "3.0.7", "json-loader": "0.5.4", diff --git a/react.js b/react.js new file mode 100644 index 0000000..b61b2e3 --- /dev/null +++ b/react.js @@ -0,0 +1 @@ +module.exports = require('./dist/jsoneditor-react') diff --git a/src/components/JSONEditor.js b/src/components/JSONEditor.js index c3ffb78..2d72956 100644 --- a/src/components/JSONEditor.js +++ b/src/components/JSONEditor.js @@ -1,7 +1,6 @@ // @flow import { createElement as h, Component, PropTypes } from 'react' -import { render, unmountComponentAtNode} from 'react-dom' import CodeMode from './CodeMode' import TextMode from './TextMode' import TreeMode from './TreeMode'