Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove regex's, fix entry module #55

Closed
wants to merge 10 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,15 @@
"globals": {
"expect": true
},
"plugins": [
"sort-requires"
],
"rules": {
"no-console": 0,
"no-trailing-spaces": 1,
"indent": ["warn", 2],
"no-console": "off",
"no-trailing-spaces": "warn",
"quotes": ["warn", "double"],
"semi": "warn",
"indent": ["warn", 2]
"sort-requires/sort-requires": "warn"
}
}
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
node_modules/
test/output
_test-output
.tmp-globalize-webpack/
125 changes: 76 additions & 49 deletions ProductionModePlugin.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
var CommonJsRequireDependency = require("webpack/lib/dependencies/CommonJsRequireDependency");
var ConcatSource = require("webpack-sources").ConcatSource;
var GlobalizeCompilerHelper = require("./GlobalizeCompilerHelper");
var ModuleFilenameHelpers = require("webpack/lib/ModuleFilenameHelpers");
var MultiEntryPlugin = require("webpack/lib/MultiEntryPlugin");
var NormalModuleFactory = require("webpack/lib/NormalModuleFactory");
var NormalModuleReplacementPlugin = require("webpack/lib/NormalModuleReplacementPlugin");
var RawModule = require("webpack/lib/RawModule");
var SkipAMDPlugin = require("skip-amd-webpack-plugin");
var util = require("./util");

Expand Down Expand Up @@ -158,14 +156,14 @@ ProductionModePlugin.prototype.apply = function(compiler) {
}
});

// Have each globalize-compiled-data chunks to include precompiled data for
// each supportedLocales. On each chunk, merge all the precompiled modules
// Have each globalize-compiled-data chunks include precompiled data for
// each supported locale. In each chunk, merge all the precompiled modules
// into a single one. Finally, allow the chunks to be loaded incrementally
// (not mutually exclusively). Details below.
//
// Up to this step, all globalize-compiled-data chunks include several
// precompiled modules, which have been mandatory to allow webpack to figure
// out the Globalize runtime dependencies. But, for the final chunk we need
// out the Globalize runtime dependencies. But for the final chunk we need
// something a little different:
//
// a) Instead of including several individual precompiled modules, it's
Expand All @@ -191,66 +189,103 @@ ProductionModePlugin.prototype.apply = function(compiler) {
// defining the formatters and parsers for its individual parents, we
// actually simplify them by returning Globalize only. The precompiled
// content for the whole set of formatters and parsers are going to be
// included in the id numbered 0 of these chunks. The id 0 has a special
// meaning in webpack, it means it's going to be executed as soon as it's
// loaded. So, we accomplish what we need: have the data loaded as soon
// as the chunk is loaded, which means it will be available when each
// included in the entry module of each of these chunks.
// So, we accomplish what we need: have the data loaded as soon as the
// chunk is loaded, which means it will be available when each
// individual parent code needs it.
//
// OBS: `additional-chunk-assets` is used to make globalize-compiled-data
// changes right before `optimize-chunk-assets` (used by plugins like
// Uglify).
//
// TODO: Can we do this differently than using regexps?
compilation.plugin("additional-chunk-assets", function(chunks) {
compilation.plugin("after-optimize-module-ids", function() {
var globalizeModuleIds = [];
var globalizeModuleIdsMap = {};

chunks.forEach(function(chunk) {
this.chunks.forEach(function(chunk) {
chunk.modules.forEach(function(module) {
var aux;
var request = module.request;
if (request && util.isGlobalizeRuntimeModule(request)) {
// While request has the full pathname, aux has something like "globalize/dist/globalize-runtime/date".
// While request has the full pathname, aux has something like
// "globalize/dist/globalize-runtime/date".
aux = request.split(/[\/\\]/);
aux = aux.slice(aux.lastIndexOf("globalize")).join("/").replace(/\.js$/, "");
globalizeModuleIds.push(module.id);
globalizeModuleIdsMap[aux] = module.id;

// some plugins, like HashedModuleIdsPlugin, may change module ids
// into strings.
var moduleId = module.id;
if (typeof moduleId === "string") {
moduleId = JSON.stringify(moduleId);
}

globalizeModuleIds.push(moduleId);
globalizeModuleIdsMap[aux] = moduleId;
}
});
});

chunks.filter(function(chunk) {
return /globalize-compiled-data/.test(chunk.name);
}).forEach(function(chunk) {
var locale = chunk.name.replace("globalize-compiled-data-", "");
chunk.files.filter(ModuleFilenameHelpers.matchObject).forEach(function(file) {
var isFirst = true;
// Match either webpack 1.x or webpack 2.x
var source = compilation.assets[file].source().replace(/\n\/\*\*\*\/ (\(?function)\(module, exports(, __webpack_require__)?\) {[\s\S]*?(\n\/\*\*\*\/ })/g, function(garbage1, fnHead, garbage2, fnTail) {
var fnContent;
// rewrite the modules in the localized chunks:
// - entry module will contain the compiled formatters and parsers
// - non-entry modules will be rewritten to export globalize
this.chunks
.filter(function(chunk) {
return /globalize-compiled-data/.test(chunk.name);
})
.forEach(function(chunk) {
// remove dead entry module for these reasons
// - because the module has no dependencies, it won't be rendered
// with __webpack_require__, making it difficult to modify its
// source in a way that can import globalize
//
// - it was a placeholder MultiModule that held no content, created
// when we added a MultiEntryPlugin
//
// - the true entry module should be globalize-compiled-data
// module, which has been created as a NormalModule
chunk.removeModule(chunk.entryModule);
chunk.entryModule = chunk.modules.find(function(module) {
return module.context.endsWith(".tmp-globalize-webpack");
});

// Define the initial module 0 as the whole formatters and parsers.
if (isFirst) {
isFirst = false;
var newModules = chunk.modules.map(function(module) {
var fnContent;
if (module === chunk.entryModule) {
// rewrite entry module to contain the globalize-compiled-data
var locale = chunk.name.replace("globalize-compiled-data-", "");
fnContent = globalizeCompilerHelper.compile(locale)
.replace("typeof define === \"function\" && define.amd", "false")
.replace(/require\("([^)]+)"\)/g, function(garbage, moduleName) {
return "__webpack_require__(" + globalizeModuleIdsMap[moduleName] + ")";
});

// Define all other individual globalize compiled data as a simple exports to Globalize.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we leave this comment? Otherwise, the else code below would be pretty confusing...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment restored.

} else {
// rewrite all other modules in this chunk as proxies for
// Globalize
fnContent = "module.exports = __webpack_require__(" + globalizeModuleIds[0] + ");";
}

return "\n/***/ " + fnHead + "(module, exports, __webpack_require__) {\n" + fnContent + fnTail;
// The `module` object in scope here is in each locale chunk, and
// any modifications we make will be rendered into every locale
// chunk. Create a new module to contain the locale-specific source
// modifications we've made.
var newModule = new RawModule(fnContent);
newModule.context = module.context;
newModule.id = module.id;
newModule.dependencies = module.dependencies;
return newModule;
});

// remove old modules with modified clones
// chunk.removeModule doesn't always find the module to remove
// ¯\_(ツ)_/¯, so we have to be be a bit more thorough here.
chunk.modules.forEach(function(module) {
module.removeChunk(chunk);
});
chunk.modules = [];

// install the rewritten modules
newModules.forEach(function(module) {
chunk.addModule(module);
});
compilation.assets[file] = new ConcatSource(source);
});
});
});


// Set the right chunks order. The globalize-compiled-data chunks must
// appear after globalize runtime modules, but before any app code.
compilation.plugin("optimize-chunk-order", function(chunks) {
Expand Down Expand Up @@ -278,17 +313,9 @@ ProductionModePlugin.prototype.apply = function(compiler) {
});
});

// Hack to support webpack 1.x and 2.x.
// webpack 2.x
if (NormalModuleFactory.prototype.createParser) {
compiler.plugin("compilation", function(compilation, params) {
params.normalModuleFactory.plugin("parser", bindParser);
});

// webpack 1.x
} else {
bindParser(compiler.parser);
}
compiler.plugin("compilation", function(compilation, params) {
params.normalModuleFactory.plugin("parser", bindParser);
});
};

module.exports = ProductionModePlugin;
2 changes: 1 addition & 1 deletion index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
var ProductionModePlugin = require("./ProductionModePlugin");
var DevelopmentModePlugin = require("./DevelopmentModePlugin");
var ProductionModePlugin = require("./ProductionModePlugin");

/**
* Development Mode:
Expand Down
13 changes: 9 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
{
"name": "globalize-webpack-plugin",
"version": "0.3.12",
"version": "0.4.0",
"description": "Globalize.js webpack plugin",
"main": "index.js",
"scripts": {
"test": "eslint *js && mocha test"
"test": "mocha test",
"test:debug": "node ./node_modules/.bin/mocha --inspect --debug-brk test",
"pretest": "npm run lint",
"lint": "eslint *js test"
},
"repository": {
"type": "git",
Expand All @@ -29,19 +32,21 @@
"peerDependencies": {
"cldr-data": ">=25",
"globalize": "^1.1.0-rc.5 <=1.3.0-a",
"webpack": "^1.9.0 || ^2.2.0-rc"
"webpack": "^2.2.0-rc"
},
"devDependencies": {
"chai": "^3.5.0",
"chai-as-promised": "^6.0.0",
"cldr-data": "^31.0.2",
"eslint": "^3.19.0",
"eslint-config-defaults": "^9.0.0",
"eslint-plugin-sort-requires": "^2.1.0",
"globalize": "^1.2.3",
"mkdirp": "^0.5.1",
"mocha": "^3.3.0",
"path-chunk-webpack-plugin": "^1.2.0",
"rimraf": "^2.6.1",
"webpack": "^1.15.0"
"webpack": "^2.5.1"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

},
"cldr-data-urls-filter": "(core|dates|numbers|units)"
}
Loading