Skip to content
This repository has been archived by the owner on May 17, 2019. It is now read-only.

Commit

Permalink
Refactor i18n discovery
Browse files Browse the repository at this point in the history
  • Loading branch information
rtsao committed Aug 30, 2018
1 parent f5aad64 commit 2c18922
Show file tree
Hide file tree
Showing 9 changed files with 106 additions and 69 deletions.
26 changes: 19 additions & 7 deletions build/compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,20 @@ const resolveFrom = require('resolve-from');

const getBabelConfig = require('./get-babel-config.js');
const LoaderContextProviderPlugin = require('./plugins/loader-context-provider-plugin.js');
const {chunkIdsLoader, fileLoader, babelLoader} = require('./loaders/index.js');
const {
chunkIdsLoader,
fileLoader,
babelLoader,
i18nManifestLoader,
} = require('./loaders/index.js');
const {DeferredState} = require('./shared-state-containers.js');
const {clientChunkIndexContextKey} = require('./loaders/loader-context.js');
const {
clientChunkIndexContextKey,
translationsManifestContextKey,
} = require('./loaders/loader-context.js');
const ChunkIndexStateHydratorPlugin = require('./plugins/chunk-index-state-hydrator-plugin');
const InstrumentedImportDependencyTemplatePlugin = require('./plugins/instrumented-import-dependency-template-plugin');
const I18nDiscoveryPlugin = require('./i18n-discovery-plugin.js');
const I18nDiscoveryPlugin = require('./plugins/i18n-discovery-plugin.js');
const ClientChunkBundleUrlMapPlugin = require('./client-chunk-bundle-url-map-plugin');
const SyncChunkIdsPlugin = require('./sync-chunk-ids-plugin');
const chalk = require('chalk');
Expand Down Expand Up @@ -291,9 +299,7 @@ function getConfig({target, env, dir, watch, state}) {
__SECRET_BUNDLE_MAP_LOADER__: require.resolve(
'./client-chunk-bundle-url-map-loader'
),
__SECRET_I18N_MANIFEST_INSTRUMENTATION_LOADER__: require.resolve(
'./i18n-manifest-instrumentation-loader.js'
),
[i18nManifestLoader.alias]: i18nManifestLoader.path,
},
},
plugins: [
Expand All @@ -305,6 +311,11 @@ function getConfig({target, env, dir, watch, state}) {
clientChunkIndexContextKey,
state.clientChunkIndex
),
target !== 'web' &&
new LoaderContextProviderPlugin(
translationsManifestContextKey,
state.i18nManifest
),
env === 'production' && zopfliWebpackPlugin, // gzip
// generate compressed files
env === 'production' && brotliWebpackPlugin, // brotli
Expand Down Expand Up @@ -336,7 +347,7 @@ function getConfig({target, env, dir, watch, state}) {
new webpack.HashedModuleIdsPlugin(),
target === 'web' && new SyncChunkIdsPlugin(),
target === 'web' && new ClientChunkBundleUrlMapPlugin(['es5'], 'es5'),
target === 'web' && new I18nDiscoveryPlugin(),
target === 'web' && new I18nDiscoveryPlugin(state.i18nManifest),
// case-insensitive paths can cause problems
new CaseSensitivePathsPlugin(),
target === 'node' &&
Expand Down Expand Up @@ -477,6 +488,7 @@ function Compiler(
) /*: CompilerType */ {
const state = {
clientChunkIndex: new DeferredState(),
i18nManifest: new DeferredState(),
};

const root = path.resolve(dir);
Expand Down
26 changes: 0 additions & 26 deletions build/i18n-discovery-plugin.js

This file was deleted.

13 changes: 0 additions & 13 deletions build/i18n-manifest-emitter.js

This file was deleted.

13 changes: 0 additions & 13 deletions build/i18n-manifest.js

This file was deleted.

19 changes: 14 additions & 5 deletions build/loaders/babel-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,15 @@ const path = require('path');
const babel = require('@babel/core');
const loaderUtils = require('loader-utils');

const i18nManifest = require('../i18n-manifest.js');
const PersistentDiskCache = require('../persistent-disk-cache.js');
const TranslationsExtractor = require('../babel-plugins/babel-plugin-i18n');

const {translationsDiscoveryKey} = require('./loader-context.js');

/*::
import type {TranslationsDiscoveryContext} from "./loader-context.js";
*/

class LoaderError extends Error {
/*::
hideStack: boolean
Expand All @@ -40,7 +45,7 @@ function webpackLoader(source /*: string */, inputSourceMap /*: Object */) {
const callback = this.async();

loader
.call(this, source, inputSourceMap)
.call(this, source, inputSourceMap, this[translationsDiscoveryKey])
.then(([code, map]) => callback(null, code, map), err => callback(err));
}

Expand All @@ -53,7 +58,11 @@ function getCache(cacheDir) {
return cache;
}

async function loader(source, inputSourceMap) {
async function loader(
source,
inputSourceMap,
discoveryState /*: TranslationsDiscoveryContext*/
) {
const filename = this.resourcePath;
const loaderOptions = loaderUtils.getOptions(this);

Expand Down Expand Up @@ -111,8 +120,8 @@ async function loader(source, inputSourceMap) {
if (result) {
const {code, map, metadata} = result;

if (metadata.translationIds) {
i18nManifest.set(filename, new Set(metadata.translationIds));
if (discoveryState && metadata.translationIds) {
discoveryState.set(filename, new Set(metadata.translationIds));
}

return [code, map];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,19 @@

/* eslint-env node */

const i18nManifest = require('./i18n-manifest-emitter.js');
const {translationsManifestContextKey} = require('./loader-context.js');

module.exports = function(/* content */) {
this.cacheable(false);
const callback = this.async();

const done = this.async();
i18nManifest.get().then(manifest => {
done(null, generateSource(manifest));
const i18nManifest = this[translationsManifestContextKey];
if (!i18nManifest) {
return void callback('no i18n manifest');
}

i18nManifest.result.then(manifest => {
return void callback(null, generateSource(manifest));
});
};

Expand Down
4 changes: 4 additions & 0 deletions build/loaders/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ const loaderIndex = {
babelLoader: {
path: require.resolve('./babel-loader.js'),
},
i18nManifestLoader: {
alias: '__SECRET_I18N_MANIFEST_INSTRUMENTATION_LOADER__',
path: require.resolve('./i18n-manifest-loader.js'),
},
};

module.exports = loaderIndex;
18 changes: 17 additions & 1 deletion build/loaders/loader-context.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@
/*eslint-env node */

/*::
import type {ChunkIndexState} from "../types.js";
import type {
ChunkIndexState,
TranslationsManifest,
TranslationsManifestState
} from "../types.js";
*/

/*::
Expand All @@ -17,3 +21,15 @@ export type ClientChunkIndexContext = ChunkIndexState;
exports.clientChunkIndexContextKey = Symbol(
'context key for client chunk index'
);

/*::
export type TranslationsManifestContext = TranslationsManifestState;
*/
exports.translationsManifestContextKey = Symbol(
'context key for translations manifest'
);

/*::
export type TranslationsDiscoveryContext = TranslationsManifest;
*/
exports.translationsDiscoveryKey = Symbol('random key');
43 changes: 43 additions & 0 deletions build/plugins/i18n-discovery-plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/** Copyright (c) 2018 Uber Technologies, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

/* eslint-env node */

const {translationsDiscoveryKey} = require('../loaders/loader-context.js');

/*::
import type {TranslationsManifestState, TranslationsManifest} from "../types.js";
*/

class I18nDiscoveryPlugin {
/*::
manifest: TranslationsManifestState;
discoveryState: TranslationsManifest;
*/
constructor(manifest /*: TranslationsManifestState*/) {
this.manifest = manifest;
this.discoveryState = new Map();
}
apply(compiler /*: any */) {
const name = this.constructor.name;
compiler.hooks.compilation.tap(name, compilation => {
compilation.hooks.normalModuleLoader.tap(name, (context, module) => {
context[translationsDiscoveryKey] = this.discoveryState;
});
});
compiler.hooks.done.tap(name, () => {
this.manifest.resolve(this.discoveryState);
});
compiler.hooks.invalid.tap(name, filename => {
this.manifest.reset();
this.discoveryState = new Map();
});
}
}

module.exports = I18nDiscoveryPlugin;

0 comments on commit 2c18922

Please sign in to comment.