From 51e1f23f69a3784b0edc296d8f0b73e7e9b0147f Mon Sep 17 00:00:00 2001 From: Jason Robitaille Date: Sun, 23 Oct 2016 14:46:47 -0700 Subject: [PATCH 01/16] Ensure invalid package names are sanitized so NPM can install dependencies correctly. --- global-cli/init.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/global-cli/init.js b/global-cli/init.js index e5c0b78e..ca09817b 100755 --- a/global-cli/init.js +++ b/global-cli/init.js @@ -31,7 +31,7 @@ function createApp(output, template, link, local, verbose) { process.chdir(root); copyTemplate(template, root); - installDeps(root,link, local, verbose, function() { + installDeps(root, link, local, verbose, function() { console.log(); console.log('Success! Created ' + appName + ' at ' + root); console.log(); @@ -90,7 +90,7 @@ function copyTemplate(template, dest) { // Update package.json name var pkgJSON = path.join(dest, 'package.json'); var meta = JSON.parse(fs.readFileSync(pkgJSON, {encoding:'utf8'})); - meta.name = path.basename(dest); + meta.name = path.basename(dest).replace(/ /g, '-').toLowerCase(); fs.writeFileSync(pkgJSON, JSON.stringify(meta, null, '\t'), {encoding:'utf8'}); // Update appinfo.json if it exists in the template From 78127b92149a48ece63c5ab37c1168007e6f6f99 Mon Sep 17 00:00:00 2001 From: Jason Robitaille Date: Sun, 23 Oct 2016 15:59:50 -0700 Subject: [PATCH 02/16] Add initial support to build standalone axternal framework --- config/EnactFrameworkPlugin.js | 71 +++++++++++++++++++++++++++++++ config/EnactFrameworkRefPlugin.js | 54 +++++++++++++++++++++++ global-cli/pack.js | 35 +++++++++++++-- 3 files changed, 157 insertions(+), 3 deletions(-) create mode 100644 config/EnactFrameworkPlugin.js create mode 100644 config/EnactFrameworkRefPlugin.js diff --git a/config/EnactFrameworkPlugin.js b/config/EnactFrameworkPlugin.js new file mode 100644 index 00000000..37bd0b63 --- /dev/null +++ b/config/EnactFrameworkPlugin.js @@ -0,0 +1,71 @@ +var + path = require('path'), + fs = require('fs'), + DllEntryPlugin = require('webpack/lib/DllEntryPlugin'); + +var pkgCache = {}; +var checkPkgMain = function(dir) { + if(pkgCache[dir]) { + return pkgCache[dir].main; + } else { + try { + var text = fs.readFileSync(path.join(dir, 'package.json'), {encoding:'utf8'}); + pkgCache[dir] = JSON.parse(text); + return pkgCache[dir].main; + } catch(e) { + return undefined; + } + } +}; + +function EnactFrameworkPlugin(options) { + this.options = options || {}; +} +module.exports = EnactFrameworkPlugin; +EnactFrameworkPlugin.prototype.apply = function(compiler) { + compiler.plugin('entry-option', function(context, entry) { + function itemToPlugin(item, name) { + if(Array.isArray(item)) + return new DllEntryPlugin(context, item, name); + else + throw new Error('EnactFrameworkPlugin: supply an Array as entry'); + } + if(typeof entry === 'object') { + Object.keys(entry).forEach(function(name) { + compiler.apply(itemToPlugin(entry[name], name)); + }); + } else { + compiler.apply(itemToPlugin(entry, 'main')); + } + return true; + }); + compiler.plugin('compilation', function(compilation) { + compilation.plugin('before-module-ids', function(modules) { + modules.forEach(function(module) { + if(module.id === null && module.libIdent) { + module.id = module.libIdent({ + context: this.options.context || compiler.options.context + }); + var parent = path.dirname(module.id); + var main = checkPkgMain(parent); + if(main && path.resolve(module.id)===path.resolve(path.join(parent, main))) { + module.id = parent; + } + module.id = module.id.replace(/\\/g, '/'); + var nodeModulesPrefix = './node_modules/'; + if(module.id.indexOf(nodeModulesPrefix)===0) { + module.id = module.id.substring(nodeModulesPrefix.length); + } + if(module.id.indexOf('node_modules')===-1) { + if(module.id.indexOf('.js')===module.id.length-3) { + module.id = module.id.substring(0, module.id.length-3); + } + if(module.id.indexOf('/index')===module.id.length-6 && module.id.length>6) { + module.id = module.id.substring(0, module.id.length-6); + } + } + } + }, this); + }.bind(this)); + }.bind(this)); +}; diff --git a/config/EnactFrameworkRefPlugin.js b/config/EnactFrameworkRefPlugin.js new file mode 100644 index 00000000..12f5f772 --- /dev/null +++ b/config/EnactFrameworkRefPlugin.js @@ -0,0 +1,54 @@ +var + ExternalsPlugin = require('webpack/lib/ExternalsPlugin'), + DelegatedSourceDependency = require('webpack/lib/dependencies/DelegatedSourceDependency'), + DelegatedModule = require('webpack/lib/DelegatedModule'); + +function DelegatedEnactFactoryPlugin(options) { + this.options = options; +} +DelegatedEnactFactoryPlugin.prototype.apply = function(normalModuleFactory) { + normalModuleFactory.plugin('factory', function(factory) { + return function(data, callback) { + var dependency = data.dependency; + var request = dependency.request; + for(var i=0; i Date: Mon, 24 Oct 2016 15:32:34 -0700 Subject: [PATCH 03/16] Add initial support for building apps with an external framework. --- config/EnactFrameworkRefPlugin.js | 65 ++++++++++++++++++------------- global-cli/pack.js | 42 +++++++++++++++----- 2 files changed, 71 insertions(+), 36 deletions(-) diff --git a/config/EnactFrameworkRefPlugin.js b/config/EnactFrameworkRefPlugin.js index 12f5f772..729ca0b4 100644 --- a/config/EnactFrameworkRefPlugin.js +++ b/config/EnactFrameworkRefPlugin.js @@ -1,54 +1,65 @@ var + path = require('path'), ExternalsPlugin = require('webpack/lib/ExternalsPlugin'), DelegatedSourceDependency = require('webpack/lib/dependencies/DelegatedSourceDependency'), DelegatedModule = require('webpack/lib/DelegatedModule'); function DelegatedEnactFactoryPlugin(options) { - this.options = options; + this.options = options || {}; } DelegatedEnactFactoryPlugin.prototype.apply = function(normalModuleFactory) { + var name = this.options.name; + var libs = this.options.libraries; normalModuleFactory.plugin('factory', function(factory) { return function(data, callback) { - var dependency = data.dependency; - var request = dependency.request; - for(var i=0; i Date: Mon, 24 Oct 2016 15:48:34 -0700 Subject: [PATCH 04/16] For serve, properly respect -b/--browser as the fklag to auto-open the browser --- global-cli/serve.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/global-cli/serve.js b/global-cli/serve.js index 926e6154..d058d49b 100755 --- a/global-cli/serve.js +++ b/global-cli/serve.js @@ -238,10 +238,12 @@ function runDevServer(host, port, protocol, shouldOpen) { clearConsole(); console.log(chalk.cyan('Starting the development server...')); console.log(); - if(host==='0.0.0.0') { - openBrowser(protocol + '://127.0.0.1:' + port + '/'); - } else { - openBrowser(protocol + '://' + host + ':' + port + '/'); + if(shouldOpen) { + if(host==='0.0.0.0') { + openBrowser(protocol + '://127.0.0.1:' + port + '/'); + } else { + openBrowser(protocol + '://' + host + ':' + port + '/'); + } } }); } From fee1c14d4168e091523c229ac78e1044aac06d9d Mon Sep 17 00:00:00 2001 From: Jason Robitaille Date: Tue, 25 Oct 2016 14:41:38 -0700 Subject: [PATCH 05/16] PLAT-29433: Add --no-minify option to enact-dev to disable any minification --- global-cli/pack.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/global-cli/pack.js b/global-cli/pack.js index b2297f3a..6a8d113b 100755 --- a/global-cli/pack.js +++ b/global-cli/pack.js @@ -95,6 +95,7 @@ function readJSON(file) { } function externalFramework(config, external, inject) { + // Add the reference plugin so the app uses the external framework config.plugins.push(new EnactFrameworkRefPlugin({ name:'enact_framework', libraries:['@enact', 'react', 'react-dom'], @@ -244,13 +245,21 @@ function displayHelp() { console.log(' -v, --version Display version information'); console.log(' -h, --help Display help information'); console.log(); + /* + Hidden Options: + --framework Builds the @enact/*, react, and react-dom into an external framework + --no-mangle Will skip mangling during production build + --externals Specify a local directory path to the standalone external framework + --externals-inject Remote public path to the external framework for use injecting into HTML + */ process.exit(0); } module.exports = function(args) { var opts = minimist(args, { - boolean: ['framework', 'p', 'production', 'i', 'isomorphic', 'w', 'watch', 'h', 'help'], + boolean: ['minify', 'framework', 'p', 'production', 'i', 'isomorphic', 'w', 'watch', 'h', 'help'], string: ['externals', 'externals-inject'], + default: {minify:true}, alias: {p:'production', i:'isomorphic', w:'watch', h:'help'} }); opts.help && displayHelp(); @@ -261,6 +270,12 @@ module.exports = function(args) { if(opts.production) { process.env.NODE_ENV = 'production'; config = prodConfig; + if(!opts['minify']) { + // Allow Uglify's optimizations/debug-code-removal but don't minify + config.plugins[4].options.mangle = false; + config.plugins[4].options.beautify = true; + config.plugins[4].options.output.comments = true; + } } else { process.env.NODE_ENV = 'development'; config = devConfig; From 9f28981214cec0e25a0cb502dcc9430a27e5d1b6 Mon Sep 17 00:00:00 2001 From: Jason Robitaille Date: Tue, 25 Oct 2016 14:42:23 -0700 Subject: [PATCH 06/16] Support prerendering of apps using external Enact framework. --- config/EnactFrameworkPlugin.js | 7 +++++++ config/EnactFrameworkRefPlugin.js | 35 +++++++++++++++++++++++++------ config/PrerenderPlugin.js | 11 +++++++++- 3 files changed, 46 insertions(+), 7 deletions(-) diff --git a/config/EnactFrameworkPlugin.js b/config/EnactFrameworkPlugin.js index 37bd0b63..ca021de9 100644 --- a/config/EnactFrameworkPlugin.js +++ b/config/EnactFrameworkPlugin.js @@ -23,6 +23,7 @@ function EnactFrameworkPlugin(options) { } module.exports = EnactFrameworkPlugin; EnactFrameworkPlugin.prototype.apply = function(compiler) { + // Map entries to the DLLEntryPlugin compiler.plugin('entry-option', function(context, entry) { function itemToPlugin(item, name) { if(Array.isArray(item)) @@ -39,6 +40,8 @@ EnactFrameworkPlugin.prototype.apply = function(compiler) { } return true; }); + + // Format the internal module ID to a usable named descriptor compiler.plugin('compilation', function(compilation) { compilation.plugin('before-module-ids', function(modules) { modules.forEach(function(module) { @@ -52,14 +55,18 @@ EnactFrameworkPlugin.prototype.apply = function(compiler) { module.id = parent; } module.id = module.id.replace(/\\/g, '/'); + + // Remove any leading ./node_modules prefix var nodeModulesPrefix = './node_modules/'; if(module.id.indexOf(nodeModulesPrefix)===0) { module.id = module.id.substring(nodeModulesPrefix.length); } if(module.id.indexOf('node_modules')===-1) { + // Remove any js file extension if(module.id.indexOf('.js')===module.id.length-3) { module.id = module.id.substring(0, module.id.length-3); } + // Remove any /index suffix as we want the user-accessible ID if(module.id.indexOf('/index')===module.id.length-6 && module.id.length>6) { module.id = module.id.substring(0, module.id.length-6); } diff --git a/config/EnactFrameworkRefPlugin.js b/config/EnactFrameworkRefPlugin.js index 729ca0b4..98f05c66 100644 --- a/config/EnactFrameworkRefPlugin.js +++ b/config/EnactFrameworkRefPlugin.js @@ -4,6 +4,8 @@ var DelegatedSourceDependency = require('webpack/lib/dependencies/DelegatedSourceDependency'), DelegatedModule = require('webpack/lib/DelegatedModule'); +// Custom DelegateFactoryPlugin designed to redirect Enact framework require() calls +// to the external framework function DelegatedEnactFactoryPlugin(options) { this.options = options || {}; } @@ -23,6 +25,16 @@ DelegatedEnactFactoryPlugin.prototype.apply = function(normalModuleFactory) { }); }; +// Form a correct filepath that can be used within the build's output directory +function normalizePath(dir, file, compiler) { + if(path.isAbsolute(dir)) { + return path.join(dir, file); + } else { + return path.relative(path.resolve(compiler.options.output.path), path.join(process.cwd(), dir, file)); + } +} + +// Reference plugin to handle rewiring the external Enact framework requests function EnactFrameworkRefPlugin(opts) { this.options = opts || {}; this.options.name = this.options.name || 'enact_framework'; @@ -41,21 +53,32 @@ EnactFrameworkRefPlugin.prototype.apply = function(compiler) { var libs = this.options.libraries; var external = this.options.external; + // Declare enact_framework as an external dependency var externals = {}; externals[name] = name; - compiler.apply(new ExternalsPlugin('var', externals)); + compiler.apply(new ExternalsPlugin(compiler.options.output.libraryTarget || 'var', externals)); compiler.plugin('compilation', function(compilation, params) { var normalModuleFactory = params.normalModuleFactory; compilation.dependencyFactories.set(DelegatedSourceDependency, normalModuleFactory); + + compilation.plugin('html-webpack-plugin-alter-chunks', function(chunks, params) { + // Add the framework files as a pseudo-chunk so they get injected into the HTML + chunks.unshift({ + names: ['enact_framework'], + files: [ + normalizePath(external.inject, 'enact.js', compiler), + normalizePath(external.inject, 'enact.css', compiler) + ] + }); - compilation.plugin('html-webpack-plugin-before-html-processing', function(params, callback) { - params.assets.js.unshift(path.join(external.inject, 'enact.js')); - params.assets.css.unshift(path.join(external.inject, 'enact.css')); - params.plugin.options.external = external; - callback(); + // Store the absolute filepath to the external framework so the PrerenderPlugin can use it + params.plugin.options.externalFramework = path.resolve(path.join(external.path, 'enact.js')); + return chunks; }); }); + + // Apply the Enact factory plugin to handle the require() delagation/rerouting compiler.plugin('compile', function(params) { params.normalModuleFactory.apply(new DelegatedEnactFactoryPlugin({ name: name, diff --git a/config/PrerenderPlugin.js b/config/PrerenderPlugin.js index f34e8775..96aff410 100644 --- a/config/PrerenderPlugin.js +++ b/config/PrerenderPlugin.js @@ -20,12 +20,16 @@ PrerenderPlugin.prototype.apply = function(compiler) { if(compiler.outputFileSystem.writeFile===NodeOutputFileSystem.prototype.writeFile) { compilation.plugin('html-webpack-plugin-after-html-processing', function(params, callback) { var appFile = path.join(compiler.context, compiler.options.output.path, 'main.js'); + + // Attempt to resolve 'react-dom/server' relative to the project itself with internal as fallback var ReactDOMServer; try { ReactDOMServer = require(path.join(compiler.context, 'node_modules', 'react-dom', 'server')); } catch(e) { ReactDOMServer = require('react-dom/server'); } + + // Add fetch to the global variables if (!global.fetch) { global.fetch = require('node-fetch'); global.Response = global.fetch.Response; @@ -33,7 +37,12 @@ PrerenderPlugin.prototype.apply = function(compiler) { global.Request = global.fetch.Request; } try { - var App = requireFromString(compilation.assets['main.js'].source(), 'main.js'); + var src = compilation.assets['main.js'].source(); + if(params.plugin.options.externalFramework) { + // Add external Enact framework filepath if it's used + src = src.replace(/require\(["']enact_framework["']\)/g, 'require("' + params.plugin.options.externalFramework + '")'); + } + var App = requireFromString(src, 'main.js'); var code = ReactDOMServer.renderToString(App['default'] || App); params.html = params.html.replace('
', '
' + code + '
'); } catch(e) { From 8f8fbf4127b4e18903d9167e32c44013d063a3bc Mon Sep 17 00:00:00 2001 From: Jason Robitaille Date: Wed, 26 Oct 2016 15:30:30 -0700 Subject: [PATCH 07/16] Grammar/syntax fixes --- global-cli/pack.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/global-cli/pack.js b/global-cli/pack.js index 6a8d113b..c5d5f6a0 100755 --- a/global-cli/pack.js +++ b/global-cli/pack.js @@ -185,7 +185,7 @@ function setupIsomorphic(config) { // Create the build and optionally, print the deployment instructions. function build(config, previousSizeMap, guided) { if(process.env.NODE_ENV === 'development') { - console.log('Creating an development build...'); + console.log('Creating a development build...'); } else { console.log('Creating an optimized production build...'); } @@ -248,7 +248,7 @@ function displayHelp() { /* Hidden Options: --framework Builds the @enact/*, react, and react-dom into an external framework - --no-mangle Will skip mangling during production build + --no-minify Will skip minification during production build --externals Specify a local directory path to the standalone external framework --externals-inject Remote public path to the external framework for use injecting into HTML */ From aaf172377c5a6d60152dab6fac04a3b223566a02 Mon Sep 17 00:00:00 2001 From: Jason Robitaille Date: Tue, 1 Nov 2016 14:40:43 -0700 Subject: [PATCH 08/16] Prevent babel from attempting to process/sourcemap sources within enact-dev, such as polyfills.js --- config/webpack.config.dev.js | 9 +-------- config/webpack.config.prod.js | 9 +-------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/config/webpack.config.dev.js b/config/webpack.config.dev.js index 6d739768..c51d9b41 100644 --- a/config/webpack.config.dev.js +++ b/config/webpack.config.dev.js @@ -101,7 +101,7 @@ module.exports = { { test: /\.(js|jsx|es6)$/, loader: 'babel', - exclude: /node_modules.(?!@*enact)/, + exclude: /node_modules.(?!@enact)/, query: { // @remove-on-eject-begin babelrc: false, @@ -251,10 +251,3 @@ module.exports = { new WebOSMetaPlugin() ] }; - -try { - fs.accessSync(path.join('node_modules', 'enact')); - module.exports.resolve.alias['@enact'] = 'enact/packages'; -} catch (err) { - delete module.exports.resolve.alias['@enact']; -} diff --git a/config/webpack.config.prod.js b/config/webpack.config.prod.js index 4f8fc376..c83254d9 100644 --- a/config/webpack.config.prod.js +++ b/config/webpack.config.prod.js @@ -93,7 +93,7 @@ module.exports = { { test: /\.(js|jsx|es6)$/, loader: 'babel', - exclude: /node_modules.(?!@*enact)/, + exclude: /node_modules.(?!@enact)/, // @remove-on-eject-begin query: { babelrc: false, @@ -249,10 +249,3 @@ module.exports = { new WebOSMetaPlugin() ] }; - -try { - fs.accessSync(path.join('node_modules', 'enact')); - module.exports.resolve.alias['@enact'] = 'enact/packages'; -} catch (err) { - delete module.exports.resolve.alias['@enact']; -} From 191f7824aca5f168d7bd5991d984e62547b29d44 Mon Sep 17 00:00:00 2001 From: Jason Robitaille Date: Wed, 2 Nov 2016 00:07:07 -0700 Subject: [PATCH 09/16] Limit babel scope to allow node_modules/@enact specifically --- config/karma.conf.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/karma.conf.js b/config/karma.conf.js index 2fd7900d..04582ca3 100644 --- a/config/karma.conf.js +++ b/config/karma.conf.js @@ -80,7 +80,7 @@ module.exports = function(karma) { }, module: { loaders: [ - {test: /\.(js|jsx|es6)$/, loader: 'babel', exclude: /node_modules.(?!@*enact)/, + {test: /\.(js|jsx|es6)$/, loader: 'babel', exclude: /node_modules.(?!@enact)/, query: { // @remove-on-eject-begin babelrc: false, From 58002dc31afef8cdcb686103e95def5ad8cca034 Mon Sep 17 00:00:00 2001 From: Jason Robitaille Date: Wed, 2 Nov 2016 12:54:41 -0700 Subject: [PATCH 10/16] Support a top-level preload static function to require all Enact framework entrypoints --- config/EnactFrameworkPlugin.js | 75 ++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 25 deletions(-) diff --git a/config/EnactFrameworkPlugin.js b/config/EnactFrameworkPlugin.js index ca021de9..1ca2bc29 100644 --- a/config/EnactFrameworkPlugin.js +++ b/config/EnactFrameworkPlugin.js @@ -1,7 +1,9 @@ var path = require('path'), fs = require('fs'), - DllEntryPlugin = require('webpack/lib/DllEntryPlugin'); + DllEntryPlugin = require('webpack/lib/DllEntryPlugin'), + DllModule = require('webpack/lib/DllModule'), + RawSource = require("webpack/lib/RawSource"); var pkgCache = {}; var checkPkgMain = function(dir) { @@ -18,18 +20,62 @@ var checkPkgMain = function(dir) { } }; +function normalizeModuleID(id) { + var parent = path.dirname(id); + var main = checkPkgMain(parent); + if(main && path.resolve(id)===path.resolve(path.join(parent, main))) { + id = parent; + } + id = id.replace(/\\/g, '/'); + + // Remove any leading ./node_modules prefix + var nodeModulesPrefix = './node_modules/'; + if(id.indexOf(nodeModulesPrefix)===0) { + id = id.substring(nodeModulesPrefix.length); + } + if(id.indexOf('node_modules')===-1) { + // Remove any js file extension + if(id.indexOf('.js')===id.length-3) { + id = id.substring(0, id.length-3); + } + // Remove any /index suffix as we want the user-accessible ID + if(id.indexOf('/index')===id.length-6 && id.length>6) { + id = id.substring(0, id.length-6); + } + } + return id; +} + +DllModule.prototype.source = function() { + var header = ''; + if(DllModule.entries[this.name]) { + header += '__webpack_require__.preload = function() {\n'; + for(var i=0; i6) { - module.id = module.id.substring(0, module.id.length-6); - } - } + module.id = normalizeModuleID(module.id) } }, this); }.bind(this)); From 48437fc5d1eb69e44f3bca59c195bbf53d911447 Mon Sep 17 00:00:00 2001 From: Jason Robitaille Date: Wed, 2 Nov 2016 13:09:56 -0700 Subject: [PATCH 11/16] Used 'load' as static function name for clarity --- config/EnactFrameworkPlugin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/EnactFrameworkPlugin.js b/config/EnactFrameworkPlugin.js index 1ca2bc29..1fed4727 100644 --- a/config/EnactFrameworkPlugin.js +++ b/config/EnactFrameworkPlugin.js @@ -49,7 +49,7 @@ function normalizeModuleID(id) { DllModule.prototype.source = function() { var header = ''; if(DllModule.entries[this.name]) { - header += '__webpack_require__.preload = function() {\n'; + header += '__webpack_require__.load = function() {\n'; for(var i=0; i Date: Wed, 2 Nov 2016 14:07:55 -0700 Subject: [PATCH 12/16] Support custom loader execution function --- config/EnactFrameworkPlugin.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/config/EnactFrameworkPlugin.js b/config/EnactFrameworkPlugin.js index 1fed4727..b0d84da2 100644 --- a/config/EnactFrameworkPlugin.js +++ b/config/EnactFrameworkPlugin.js @@ -49,9 +49,10 @@ function normalizeModuleID(id) { DllModule.prototype.source = function() { var header = ''; if(DllModule.entries[this.name]) { - header += '__webpack_require__.load = function() {\n'; + header += '__webpack_require__.load = function(loader) {\n'; + header += '\tloader = loader || __webpack_require__;' for(var i=0; i Date: Wed, 2 Nov 2016 15:07:03 -0700 Subject: [PATCH 13/16] PLAT-29861: webpack bundle analysis support --- global-cli/pack.js | 18 ++++++++++++++++-- package.json | 1 + 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/global-cli/pack.js b/global-cli/pack.js index c5d5f6a0..2e4ff9ab 100755 --- a/global-cli/pack.js +++ b/global-cli/pack.js @@ -24,6 +24,7 @@ var EnactFrameworkPlugin = require('../config/EnactFrameworkPlugin'), EnactFrameworkRefPlugin = require('../config/EnactFrameworkRefPlugin'), PrerenderPlugin = require('../config/PrerenderPlugin'), + BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin, checkRequiredFiles = require('react-dev-utils/checkRequiredFiles'), recursive = require('recursive-readdir'), stripAnsi = require('strip-ansi'); @@ -182,6 +183,14 @@ function setupIsomorphic(config) { } } +function statsAnalyzer(config) { + config.plugins.push(new BundleAnalyzerPlugin({ + analyzerMode: 'static', + reportFilename: 'stats.html', + openAnalyzer: false + })); +} + // Create the build and optionally, print the deployment instructions. function build(config, previousSizeMap, guided) { if(process.env.NODE_ENV === 'development') { @@ -238,6 +247,7 @@ function displayHelp() { console.log(' enact pack [options]'); console.log(); console.log(' Options'); + console.log(' -s, --stats Output bundle analysis file'); console.log(' -w, --watch Rebuild on file changes'); console.log(' -p, --production Build in production mode'); console.log(' -i, --isomorphic Use isomorphic code layout'); @@ -257,10 +267,10 @@ function displayHelp() { module.exports = function(args) { var opts = minimist(args, { - boolean: ['minify', 'framework', 'p', 'production', 'i', 'isomorphic', 'w', 'watch', 'h', 'help'], + boolean: ['minify', 'framework', 's', 'stats', 'p', 'production', 'i', 'isomorphic', 'w', 'watch', 'h', 'help'], string: ['externals', 'externals-inject'], default: {minify:true}, - alias: {p:'production', i:'isomorphic', w:'watch', h:'help'} + alias: {s:'stats', p:'production', i:'isomorphic', w:'watch', h:'help'} }); opts.help && displayHelp(); @@ -292,6 +302,10 @@ module.exports = function(args) { } } + if(opts.stats) { + statsAnalyzer(config); + } + // Warn and crash if required files are missing if (!opts.framework && !checkRequiredFiles([config.entry.main[config.entry.main.length-1]])) { process.exit(1); diff --git a/package.json b/package.json index d85ad97b..be6b878d 100644 --- a/package.json +++ b/package.json @@ -87,6 +87,7 @@ "style-loader": "~0.13.1", "webos-meta-webpack-plugin": "github:enyojs/webos-meta-webpack-plugin", "webpack": "~1.13.2", + "webpack-bundle-analyzer": "~1.4.1", "webpack-dev-server": "~1.16.2", "whatwg-fetch": "~1.0.0" } From 2a4b64652255eb48de4112aa0bff448ca7e98e62 Mon Sep 17 00:00:00 2001 From: Jason Robitaille Date: Thu, 3 Nov 2016 14:48:57 -0700 Subject: [PATCH 14/16] PLAT-29023: Update eslint options to add new options --- global-cli/lint.js | 4 ++-- package.json | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/global-cli/lint.js b/global-cli/lint.js index 712aad5e..c439ba39 100755 --- a/global-cli/lint.js +++ b/global-cli/lint.js @@ -28,9 +28,9 @@ module.exports = function(args) { var eslintArgs = []; if(opts.strict || opts.framework) { - eslintArgs.push('--no-eslintrc', '--config', require.resolve('eslint-config-enact-internal/index.js')); + eslintArgs.push('--no-eslintrc', '--config', require.resolve('eslint-config-enact/strict')); } else if(!opts.local) { - eslintArgs.push('--no-eslintrc', '--config', require.resolve('eslint-config-enact/index.js')); + eslintArgs.push('--no-eslintrc', '--config', require.resolve('eslint-config-enact')); } eslintArgs.push('--ignore-pattern', 'node_modules/*'); eslintArgs.push('--ignore-pattern', 'build/*'); diff --git a/package.json b/package.json index d85ad97b..29fbe08b 100644 --- a/package.json +++ b/package.json @@ -30,12 +30,12 @@ "dirty-chai": "~1.2.2", "enyo-console-spy": "enyojs/enyo-console-spy", "enzyme": "~2.4.1", - "eslint": "~3.7.1", + "eslint": "~3.9.1", "eslint-config-enact": "github:enyojs/eslint-config-enact", - "eslint-config-enact-internal": "github:enyojs/eslint-config-enact-internal", - "eslint-loader": "~1.5.0", + "eslint-loader": "~1.6.1", "eslint-plugin-babel": "~3.3.0", - "eslint-plugin-react": "~6.4.0", + "eslint-plugin-enact": "github:enyojs/eslint-plugin-enact", + "eslint-plugin-react": "~6.5.0", "expose-loader": "~0.7.1", "extract-text-webpack-plugin": "~1.0.1", "file-loader": "~0.9.0", From 613ac87d51de2e75cc10cc32e368e4f1f00eba8c Mon Sep 17 00:00:00 2001 From: Aaron Tam Date: Fri, 4 Nov 2016 15:01:41 -0700 Subject: [PATCH 15/16] Minor grammar fix Issue: PLAT-29602 Enyo-DCO-1.1-Signed-off-by: Aaron Tam --- global-cli/pack.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/global-cli/pack.js b/global-cli/pack.js index 2e4ff9ab..1b0fa5d6 100755 --- a/global-cli/pack.js +++ b/global-cli/pack.js @@ -155,7 +155,7 @@ function setupIsomorphic(config) { // The App entrypoint for isomorphics builds *must* export a ReactElement. config.entry.main[config.entry.main.length-1] = path.resolve(enact.isomorphic || enact.prerender); - // Since we're building for isomorphic usage, expose ReactElement + // Since we're building for isomorphic usage, expose ReactElement config.output.library = 'App'; // Use universal module definition to allow usage in Node and browser environments. @@ -228,7 +228,7 @@ function build(config, previousSizeMap, guided) { // Create the build and watch for changes. function watch(config) { if(process.env.NODE_ENV === 'development') { - console.log('Creating an development build and watching for changes...'); + console.log('Creating a development build and watching for changes...'); } else { console.log('Creating an optimized production build and watching for changes...'); } From 287725a32a1dc2ba37e3f199074935de9d50a721 Mon Sep 17 00:00:00 2001 From: Jason Robitaille Date: Mon, 7 Nov 2016 14:52:20 -0800 Subject: [PATCH 16/16] Updated versioning, changelog, and cleanup (#18) * Updated versioning, changelog, and cleanup * Version bump in eslint-config-enact to disable jsdoc rule. Reviewed-By: Ryan Duffy (ryan.duffy@lge.com) Integrated-By: Aaron Tam (aaron.tam@lge.com) --- CHANGELOG.md | 25 +++++++++++-- index.js | 83 +++++-------------------------------------- package.json | 46 ++++++++++++------------ template/package.json | 12 +++---- 4 files changed, 60 insertions(+), 106 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd12754a..c1847124 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,24 @@ -## 0.2.0 (October 14, 2016) +## 0.3.0 (November 7, 2016) + +### init + +* Sanitizes directory name so only valid characters are included as the package name. + +### pack + +* Added `-s`/`--stats` flag to generate a stats.html bundle analysis report. +* Fixed development build failure when generating sourcemaps. +* Refactored ESLint configuration with an optional strict mode. +* Updated `eslint` to use 3.9.1 for new rule support. +* Updated `eslint-plugin-enact` to 6.5.0 for new rule support. + +### serve + +* Browser no longer automatically opens. Use `-b`/`--browser` flag to re-enable the feature. +* Fixed serve failure when generating sourcemaps. + + +## 0.2.0 (October 21, 2016) * Refactored entire project into a dedicated standalone global CLI with features/functionality integrated from [create-react-app](https://github.com/facebookincubator/create-react-app) @@ -17,7 +37,8 @@ ### pack -* Switched from using `babel-polyfill` to a more simpliffied set of polyfills covering Promise, Object.assign, and Fetch APIs +* Switched from using `babel-polyfill` to a more simplified set of polyfills covering Promise, Object.assign, + String.prototype.codePointAt, String.fromCodePoint, Math.sign, and Fetch APIs * Scans files with ESLint as part of the build process, failing on errors. * Switched from OS-level to a local ./node_modules/.cache/ location for babel caching in development mode. * Support auto-prefixing of CSS. diff --git a/index.js b/index.js index fbd654bf..dae808f3 100644 --- a/index.js +++ b/index.js @@ -1,77 +1,10 @@ -var - path = require('path'), - fs = require('fs'), - appConfig = require('./src/app-config'), - isoConfig = require('./src/iso-config'), - containerConfig = require('./src/container-app-config'), - libConfig = require('./src/library-config'), - karmaConfig = require('./src/karma-config'), - mixin = require('./src/mixin'), - entrypoint = require('./src/entrypoint'); - -var opts; -try { - var obj = JSON.parse(fs.readFileSync('./package.json', {encoding:'utf8'})); - opts = obj.enact || {}; -} catch(e) { - opts = {}; -} - -var customProps = ['name', 'title', 'namedLibs', 'ri', 'htmlTemplate', 'prerender', 'alwaysPrerender', 'screenTypes']; - -var setup = function(config, overrides, entryDeps) { - for(var i=0; i-1 || opts.alwaysPrerender)) ? isoConfig(opts) : null; - var entries = [require.resolve('babel-polyfill')]; - if(process.argv.indexOf('-p')==-1) { - entries.push(require.resolve('react-addons-perf')); - } - var out = [setup(app, opts, entries)]; - if(iso) { - out.unshift(mixin(iso, opts)); - } - return out.length===1 ? out[0] : out; - } - }, - container: function(args) { - opts = mixin(opts, args || {}); - var c = containerConfig(opts); - return setup(c, opts, []); - }, - library: function(args) { - opts = mixin(opts, args || {}); - var c = libConfig(opts); - return setup(c, opts, []); - }, - karma: function(args) { - opts = mixin(opts, args || {}); - return (function(karmaObj) { - var c = karmaConfig({karma:karmaObj, ri:opts.ri}); - karmaObj.set(mixin(c, opts || {})); - }); - }, - eslint: require('eslint-config-enact'), - babelrc: path.join(__dirname, 'src', '.babelrc'), - webpack: require('webpack'), - ExtractTextPlugin: require('extract-text-webpack-plugin'), - HtmlWebpackPlugin: require('html-webpack-plugin'), - NamedLibraryPlugin: require('./src/NamedLibraryPlugin'), - NamedLibraryRefPlugin: require('./src/NamedLibraryRefPlugin'), - LessPluginRi: require('resolution-independence') -}; + init: require('./global-cli/init'), + pack: require('./global-cli/pack'), + serve: require('./global-cli/serve'), + clean: require('./global-cli/clean'), + lint: require('./global-cli/lint'), + test: require('./global-cli/test'), + transpile: require('./global-cli/transpile') +} \ No newline at end of file diff --git a/package.json b/package.json index ce50d43e..23e9d9ed 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "enact-dev", - "version": "0.2.0", + "version": "0.3.0", "description": "Full-featured build environment for Enact applications.", "main": "index.js", "author": "Jason Robitaille ", @@ -10,43 +10,43 @@ "enact": "./bin/enact.js" }, "dependencies": { - "autoprefixer": "~6.5.0", - "babel-core": "~6.17.0", - "babel-eslint": "~7.0.0", - "babel-loader": "~6.2.5", + "autoprefixer": "~6.5.2", + "babel-core": "~6.18.2", + "babel-eslint": "~7.1.0", + "babel-loader": "~6.2.7", "babel-plugin-dev-expression": "~0.2.1", "babel-plugin-transform-react-constant-elements": "~6.9.1", "babel-plugin-transform-react-inline-elements": "~6.8.0", - "babel-preset-es2015": "~6.16.0", + "babel-preset-es2015": "~6.18.0", "babel-preset-react": "~6.16.0", "babel-preset-stage-0": "~6.16.0", "case-sensitive-paths-webpack-plugin": "~1.1.4", "chai": "~3.5.0", "chalk": "~1.1.3", "connect-history-api-fallback": "~1.3.0", - "cross-spawn": "~4.0.2", + "cross-spawn": "~5.0.1", "css-loader": "~0.25.0", - "detect-port": "~1.0.1", + "detect-port": "~1.0.5", "dirty-chai": "~1.2.2", "enyo-console-spy": "enyojs/enyo-console-spy", - "enzyme": "~2.4.1", + "enzyme": "~2.5.1", "eslint": "~3.9.1", - "eslint-config-enact": "github:enyojs/eslint-config-enact", + "eslint-config-enact": "enyojs/eslint-config-enact#1.1.1", "eslint-loader": "~1.6.1", "eslint-plugin-babel": "~3.3.0", - "eslint-plugin-enact": "github:enyojs/eslint-plugin-enact", - "eslint-plugin-react": "~6.5.0", + "eslint-plugin-enact": "enyojs/eslint-plugin-enact#0.1.0", + "eslint-plugin-react": "~6.6.0", "expose-loader": "~0.7.1", "extract-text-webpack-plugin": "~1.0.1", "file-loader": "~0.9.0", "filesize": "~3.3.0", "find-cache-dir": "~0.1.1", - "fs-extra": "~0.30.0", + "fs-extra": "~1.0.0", "glob": "~7.1.1", - "graceful-fs-webpack-plugin": "github:enyojs/graceful-fs-webpack-plugin", - "html-webpack-plugin": "~2.22.0", + "graceful-fs-webpack-plugin": "enyojs/graceful-fs-webpack-plugin#0.1.0", + "html-webpack-plugin": "~2.24.1", "http-proxy-middleware": "~0.17.2", - "ilib-loader": "enyojs/ilib-loader", + "ilib-loader": "enyojs/ilib-loader#0.1.1", "json-loader": "~0.5.4", "karma": "~1.3.0", "karma-babel-preprocessor": "~6.0.1", @@ -61,19 +61,19 @@ "less": "~2.7.1", "less-loader": "~2.2.3", "minimist": "~1.2.0", - "mocha": "~3.1.0", + "mocha": "~3.1.2", "ncp": "~2.0.0", "node-fetch": "^1.6.3", "object-assign": "~4.1.0", "path-exists": "~3.0.0", "phantomjs-prebuilt": "~2.1.13", - "postcss-loader": "~0.13.0", + "postcss-loader": "~1.1.0", "postcss-remove-classes": "~1.0.2", "promise": "~7.1.1", "react": "~15.3.2", "react-addons-perf": "~15.3.2", "react-addons-test-utils": "~15.3.2", - "react-dev-utils": "~0.2.1", + "react-dev-utils": "~0.3.0", "react-dom": "~15.3.2", "recursive-readdir": "~2.1.0", "require-from-string": "^1.2.1", @@ -81,12 +81,12 @@ "rimraf": "~2.5.4", "semver": "~5.3.0", "sinon": "git+https://github.com/sinonjs/sinon.git", - "string.fromcodepoint": "^0.2.1", - "string.prototype.codepointat": "^0.2.0", + "string.fromcodepoint": "~0.2.1", + "string.prototype.codepointat": "~0.2.0", "strip-ansi": "~3.0.1", "style-loader": "~0.13.1", - "webos-meta-webpack-plugin": "github:enyojs/webos-meta-webpack-plugin", - "webpack": "~1.13.2", + "webos-meta-webpack-plugin": "enyojs/webos-meta-webpack-plugin#0.1.1", + "webpack": "~1.13.3", "webpack-bundle-analyzer": "~1.4.1", "webpack-dev-server": "~1.16.2", "whatwg-fetch": "~1.0.0" diff --git a/template/package.json b/template/package.json index 60a778ba..514686d6 100644 --- a/template/package.json +++ b/template/package.json @@ -28,12 +28,12 @@ "extends": "enact" }, "dependencies": { - "@enact/core": "^1.0.0-alpha.2", - "@enact/ui": "^1.0.0-alpha.2", - "@enact/moonstone": "^1.0.0-alpha.2", - "@enact/spotlight": "^1.0.0-alpha.2", - "@enact/i18n": "^1.0.0-alpha.2", - "@enact/webos": "^1.0.0-alpha.2", + "@enact/core": "^1.0.0-alpha.3", + "@enact/ui": "^1.0.0-alpha.3", + "@enact/moonstone": "^1.0.0-alpha.3", + "@enact/spotlight": "^1.0.0-alpha.3", + "@enact/i18n": "^1.0.0-alpha.3", + "@enact/webos": "^1.0.0-alpha.3", "react": "^15.3.2", "react-dom": "^15.3.2" }