Skip to content

Commit

Permalink
0.3.0 release
Browse files Browse the repository at this point in the history
  • Loading branch information
JayCanuck committed Nov 8, 2016
2 parents 332506a + 287725a commit 58b35b4
Show file tree
Hide file tree
Showing 14 changed files with 369 additions and 143 deletions.
25 changes: 23 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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)
Expand All @@ -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.
Expand Down
104 changes: 104 additions & 0 deletions config/EnactFrameworkPlugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
var
path = require('path'),
fs = require('fs'),
DllEntryPlugin = require('webpack/lib/DllEntryPlugin'),
DllModule = require('webpack/lib/DllModule'),
RawSource = require("webpack/lib/RawSource");

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 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__.load = function(loader) {\n';
header += '\tloader = loader || __webpack_require__;'
for(var i=0; i<DllModule.entries[this.name].length; i++) {
header += '\tloader(\'' + DllModule.entries[this.name][i] + '\');\n';
}
header += '};\n';
}
return new RawSource(header + 'module.exports = __webpack_require__;');
};

function EnactFrameworkPlugin(options) {
this.options = options || {};
}
module.exports = EnactFrameworkPlugin;
EnactFrameworkPlugin.prototype.apply = function(compiler) {
// Map entries to the DLLEntryPlugin
DllModule.entries = {};
compiler.plugin('entry-option', function(context, entry) {
function itemToPlugin(item, name) {
if(Array.isArray(item)) {
DllModule.entries[name] = [];
for(var i=0; i<item.length; i++) {
DllModule.entries[name].push(normalizeModuleID('./node_modules/' + item[i]));
}
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;
});

// 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) {
if(module.id === null && module.libIdent) {
module.id = module.libIdent({
context: this.options.context || compiler.options.context
});
module.id = normalizeModuleID(module.id)
}
}, this);
}.bind(this));
}.bind(this));
};
88 changes: 88 additions & 0 deletions config/EnactFrameworkRefPlugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
var
path = require('path'),
ExternalsPlugin = require('webpack/lib/ExternalsPlugin'),
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 || {};
}
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 request = data.dependency.request;
for(var i=0; i<libs.length; i++) {
if(request && request.indexOf(libs[i]) === 0) {
return callback(null, new DelegatedModule(name, request, 'require', request));
}
}
return factory(data, callback);
};
});
};

// 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';
this.options.libraries = this.options.libraries || ['@enact', 'react', 'react-dom'];
this.options.external = this.options.external || {};
this.options.external.inject = this.options.external.inject || this.options.external.path;

if(!process.env.ILIB_LOCALE_PATH) {
process.env.ILIB_LOCALE_PATH = path.join(this.options.external.inject, 'node_module',
'@enact', 'i18n', 'ilib', 'locale');
}
}
module.exports = EnactFrameworkRefPlugin;
EnactFrameworkRefPlugin.prototype.apply = function(compiler) {
var name = this.options.name;
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(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)
]
});

// 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,
libraries: libs,
}));
});
};
11 changes: 10 additions & 1 deletion config/PrerenderPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,29 @@ 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;
global.Headers = global.fetch.Headers;
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('<div id="root"></div>', '<div id="root">' + code + '</div>');
} catch(e) {
Expand Down
2 changes: 1 addition & 1 deletion config/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
9 changes: 1 addition & 8 deletions config/webpack.config.dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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'];
}
9 changes: 1 addition & 8 deletions config/webpack.config.prod.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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'];
}
4 changes: 2 additions & 2 deletions global-cli/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions global-cli/lint.js
Original file line number Diff line number Diff line change
Expand Up @@ -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/*');
Expand Down
Loading

0 comments on commit 58b35b4

Please sign in to comment.