Skip to content

Commit

Permalink
feat: support global-scope-name (#38)
Browse files Browse the repository at this point in the history
  • Loading branch information
teppeis authored Mar 28, 2019
1 parent b465f7f commit 330aeb6
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 23 deletions.
1 change: 1 addition & 0 deletions examples/chunks/entry-config/entries/chunks.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"inherits": "../base.json",
"module-output-path": "../build/chunks/%s.js",
"module-production-uri": "/build/chunks/%s.js",
"global-scope-name": "GSN_CHUNKS",
"modules": {
"chunks": {
"inputs": ["../js/chunks_init.js", "../js/chunks.js"],
Expand Down
3 changes: 2 additions & 1 deletion src/commands/serve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,12 @@ export function serve(config: DuckConfig) {

function replyChunksRaw(reply: fastify.FastifyReply<ServerResponse>, entryConfig: EntryConfig) {
const modules = assertNonNullable(entryConfig.modules);
const {moduleInfo, moduleUris, rootId} = convertModuleInfos(entryConfig, id => {
const {moduleInfo, moduleUris} = convertModuleInfos(entryConfig, id => {
return inputsToUrisForRaw(modules[id].inputs);
});
// The root chunk loads all chunks in RAW mode
const sortedChunkIds = createDag(entryConfig).getSortedIds();
const rootId = sortedChunkIds[0];
moduleUris[rootId] = flat(sortedChunkIds.map(id => moduleUris[id]));
for (const id in moduleUris) {
if (id !== rootId) {
Expand Down
66 changes: 46 additions & 20 deletions src/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,22 @@ export interface CompilerOptions {
chunk_wrapper?: string[];
chunk_output_path_prefix?: string;
isolation_mode?: 'NONE' | 'IIFE';
rename_prefix_namespace?: string;
jscomp_error?: string[];
jscomp_warning?: string[];
jscomp_off?: string[];
flagfile?: string;

// TODO:
// - output_wrapper?: string;
}

/**
* Used for `rename_prefix_namespace` if `global-scope-name` is enabled in entry config.
* @see https://github.com/bolinfest/plovr/blob/v8.0.0/src/org/plovr/Config.java#L81-L93
*/
const GLOBAL_NAMESPACE = 'z';

type CompilerOptionsFormattingType = 'PRETTY_PRINT' | 'PRINT_INPUT_DELIMITER' | 'SINGLE_QUOTES';

function createBaseOptions(entryConfig: EntryConfig, outputToFile: boolean): CompilerOptions {
Expand All @@ -57,6 +67,10 @@ function createBaseOptions(entryConfig: EntryConfig, outputToFile: boolean): Com
copy('level', 'warning_level');
copy('debug');

if (entryConfig['global-scope-name']) {
opts.rename_prefix_namespace = GLOBAL_NAMESPACE;
}

if (entryConfig.mode === PlovrMode.RAW) {
opts.compilation_level = 'WHITESPACE';
} else {
Expand Down Expand Up @@ -223,14 +237,36 @@ export async function createCompilerOptionsForChunks(
const numOfInputs = chunkToInputPathSet.get(id)!.size;
return `${id}:${numOfInputs}:${modules[id].deps.join(',')}`;
});
const {moduleInfo, moduleUris, rootId} = convertModuleInfos(entryConfig, createModuleUris);
const wrapper = stripIndents`
var PLOVR_MODULE_INFO=${JSON.stringify(moduleInfo)};
var PLOVR_MODULE_URIS=${JSON.stringify(moduleUris)};
${entryConfig.debug ? 'var PLOVR_MODULE_USE_DEBUG_MODE=true;' : ''}
%output%`.replace(/\n+/g, '%n%');
options.chunk_wrapper = [`${rootId}:${wrapper}`];
return {options, sortedChunkIds, rootChunkId: rootId};
options.chunk_wrapper = createChunkWrapper(entryConfig, sortedChunkIds, createModuleUris);
return {options, sortedChunkIds, rootChunkId: sortedChunkIds[0]};
}

function createChunkWrapper(
entryConfig: EntryConfig,
sortedChunkIds: string[],
createModuleUris: (id: string) => string[]
): string[] {
const {moduleInfo, moduleUris} = convertModuleInfos(entryConfig, createModuleUris);
return sortedChunkIds.map((chunkId, index) => {
const isRootChunk = index === 0;
let wrapper = '%output%';
if (entryConfig['global-scope-name']) {
const globalScope = entryConfig['global-scope-name'];
wrapper = stripIndents`
${isRootChunk ? `var ${globalScope}={};` : ''}
(function(${GLOBAL_NAMESPACE}){
${wrapper}
}).call(this,${globalScope});`;
}
if (isRootChunk) {
wrapper = stripIndents`
var PLOVR_MODULE_INFO=${JSON.stringify(moduleInfo)};
var PLOVR_MODULE_URIS=${JSON.stringify(moduleUris)};
${entryConfig.debug ? 'var PLOVR_MODULE_USE_DEBUG_MODE=true;' : ''}
${wrapper}`;
}
return `${chunkId}:${wrapper.replace(/\n+/g, '%n%')}`;
});
}

function findTransitiveDeps(
Expand Down Expand Up @@ -284,26 +320,16 @@ function splitDepsIntoChunks(
export function convertModuleInfos(
entryConfig: EntryConfig,
createModuleUris: (id: string) => string[]
): {moduleInfo: {[id: string]: string[]}; moduleUris: {[id: string]: string[]}; rootId: string} {
let rootId: string | null = null;
): {moduleInfo: {[id: string]: string[]}; moduleUris: {[id: string]: string[]}} {
const modules = assertNonNullable(entryConfig.modules);
const moduleInfo: {[id: string]: string[]} = {};
const moduleUris: {[id: string]: string[]} = {};
for (const id in modules) {
const module = modules[id];
moduleInfo[id] = module.deps;
moduleUris[id] = createModuleUris(id);
if (module.deps.length === 0) {
if (rootId) {
throw new Error('Many root modules');
}
rootId = id;
}
}
if (!rootId) {
throw new Error('No root module');
}
return {moduleInfo, moduleUris, rootId};
return {moduleInfo, moduleUris};
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/entryconfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ export interface EntryConfig {
checks?: {
[error: string]: 'OFF' | 'WARNING' | 'ERROR';
};
'global-scope-name'?: string;

// TODO
// * experimental-compiler-options: Object<string, any>
// * global-scope-name: `__CBZ__`
// * soy-function-plugins: string[]
// * output-wrapper
}

export enum PlovrMode {
Expand Down
2 changes: 2 additions & 0 deletions test/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ describe('compiler', () => {
'pretty-print': true,
'print-input-delimiter': true,
'test-excludes': ['/ignored'],
'global-scope-name': 'GSN',
define: {
'goog.BOOLEAN': false,
'goog.NUMBER': 100,
Expand All @@ -68,6 +69,7 @@ describe('compiler', () => {
warning_level: 'VERBOSE',
debug: true,
formatting: ['PRETTY_PRINT', 'PRINT_INPUT_DELIMITER'],
rename_prefix_namespace: 'z', // "z" is hard coded
define: ['goog.BOOLEAN=false', 'goog.NUMBER=100', "goog.STRING='single-quoted'"],
js_output_file: '/out.js',
jscomp_error: ['checkRegExp', 'deprecated'],
Expand Down

0 comments on commit 330aeb6

Please sign in to comment.