@ampproject/rollup-plugin-closure-compiler
Advanced tools
Comparing version 0.4.2 to 0.4.3
'use strict'; | ||
var tempWrite = require('temp-write'); | ||
var googleClosureCompiler = require('google-closure-compiler'); | ||
var tempWrite = require('temp-write'); | ||
var fs = require('fs'); | ||
@@ -218,5 +218,76 @@ var util = require('util'); | ||
*/ | ||
/** | ||
* Checks if output format is ESM | ||
* @param format | ||
* @return boolean | ||
*/ | ||
const isESMFormat = (format) => { | ||
// TODO: remove `| 'esm'` when rollup upgrades its typings | ||
return format === 'esm' || format === 'es'; | ||
}; | ||
/** | ||
* Generate default Closure Compiler CompileOptions an author can override if they wish. | ||
* These must be derived from configuration or input sources. | ||
* @param transformers | ||
* @param options | ||
* @return derived CompileOptions for Closure Compiler | ||
*/ | ||
const defaults = (options, transformers) => { | ||
// Defaults for Rollup Projects are slightly different than Closure Compiler defaults. | ||
// - Users of Rollup tend to transpile their code before handing it to a minifier, | ||
// so no transpile is default. | ||
// - When Rollup output is set to "es" it is expected the code will live in a ES Module, | ||
// so safely be more aggressive in minification. | ||
// - When Rollup is configured to output an iife, ensure Closure Compiler does not | ||
// mangle the name of the iife wrapper. | ||
const externs = transformers | ||
? transformers.map(transform => tempWrite.sync(transform.extern(options))) | ||
: ''; | ||
return { | ||
language_out: 'NO_TRANSPILE', | ||
assume_function_wrapper: isESMFormat(options.format) ? true : false, | ||
warning_level: 'QUIET', | ||
externs, | ||
}; | ||
}; | ||
/** | ||
* Compile Options is the final configuration to pass into Closure Compiler. | ||
* defaultCompileOptions are overrideable by ones passed in directly to the plugin | ||
* but the js source and sourcemap are not overrideable, since this would break the output if passed. | ||
* @param compileOptions | ||
* @param outputOptions | ||
* @param code | ||
* @param transforms | ||
*/ | ||
function options (compileOptions, outputOptions, code, transforms) { | ||
const mapFile = tempWrite.sync(''); | ||
return [ | ||
{ | ||
...defaults(outputOptions, transforms), | ||
...compileOptions, | ||
js: tempWrite.sync(code), | ||
create_source_map: mapFile, | ||
}, | ||
mapFile, | ||
]; | ||
} | ||
/** | ||
* Copyright 2018 The AMP HTML Authors. All Rights Reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS-IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
const HEADER$1 = `/** | ||
* @fileoverview Externs built via derived configuration from Rollup or input code. | ||
* This extern contains top level exported members. | ||
* This extern contains top level exported members. | ||
* @externs | ||
@@ -226,3 +297,3 @@ */ | ||
/** | ||
* This Transform will apply only if the Rollup configuration is for 'es' output. | ||
* This Transform will apply only if the Rollup configuration is for 'esm' output. | ||
* | ||
@@ -239,5 +310,5 @@ * In order to preserve the export statements: | ||
} | ||
extern(options) { | ||
extern(options$$1) { | ||
let content = HEADER$1; | ||
if (options.format === 'es') { | ||
if (isESMFormat(options$$1.format)) { | ||
Object.keys(this.exported).forEach(key => { | ||
@@ -297,3 +368,3 @@ content += `window['${key}'] = ${key};\n`; | ||
} | ||
else if (this.outputOptions.format === 'es') { | ||
else if (isESMFormat(this.outputOptions.format)) { | ||
Object.keys(this.exported).forEach(key => { | ||
@@ -319,3 +390,3 @@ code += `\nwindow['${key}'] = ${key}`; | ||
} | ||
else if (this.outputOptions.format === 'es') { | ||
else if (isESMFormat(this.outputOptions.format)) { | ||
const exportedConstants = []; | ||
@@ -404,3 +475,3 @@ Object.keys(this.exported).forEach(key => { | ||
} | ||
else if (this.outputOptions.format === 'es' && code.startsWith(STRICT_MODE_DECLARATION)) { | ||
else if (isESMFormat(this.outputOptions.format) && code.startsWith(STRICT_MODE_DECLARATION)) { | ||
// This will only remove the top level 'use strict' directive since we cannot | ||
@@ -535,64 +606,2 @@ // be certain source does not contain strings with the intended content. | ||
*/ | ||
/** | ||
* Generate default Closure Compiler CompileOptions an author can override if they wish. | ||
* These must be derived from configuration or input sources. | ||
* @param transformers | ||
* @param options | ||
* @return derived CompileOptions for Closure Compiler | ||
*/ | ||
const defaults = (options, transformers) => { | ||
// Defaults for Rollup Projects are slightly different than Closure Compiler defaults. | ||
// - Users of Rollup tend to transpile their code before handing it to a minifier, | ||
// so no transpile is default. | ||
// - When Rollup output is set to "es" it is expected the code will live in a ES Module, | ||
// so safely be more aggressive in minification. | ||
// - When Rollup is configured to output an iife, ensure Closure Compiler does not | ||
// mangle the name of the iife wrapper. | ||
const externs = transformers | ||
? transformers.map(transform => tempWrite.sync(transform.extern(options))) | ||
: ''; | ||
return { | ||
language_out: 'NO_TRANSPILE', | ||
assume_function_wrapper: options.format === 'es' ? true : false, | ||
warning_level: 'QUIET', | ||
externs, | ||
}; | ||
}; | ||
/** | ||
* Compile Options is the final configuration to pass into Closure Compiler. | ||
* defaultCompileOptions are overrideable by ones passed in directly to the plugin | ||
* but the js source and sourcemap are not overrideable, since this would break the output if passed. | ||
* @param compileOptions | ||
* @param outputOptions | ||
* @param code | ||
* @param transforms | ||
*/ | ||
function options (compileOptions, outputOptions, code, transforms) { | ||
const mapFile = tempWrite.sync(''); | ||
return [ | ||
{ | ||
...defaults(outputOptions, transforms), | ||
...compileOptions, | ||
js: tempWrite.sync(code), | ||
create_source_map: mapFile, | ||
}, | ||
mapFile, | ||
]; | ||
} | ||
/** | ||
* Copyright 2018 The AMP HTML Authors. All Rights Reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS-IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
const readFile = util.promisify(fs.readFile); | ||
@@ -599,0 +608,0 @@ /** |
{ | ||
"name": "@ampproject/rollup-plugin-closure-compiler", | ||
"version": "0.4.2", | ||
"version": "0.4.3", | ||
"description": "Rollup + Google Closure Compiler", | ||
@@ -54,3 +54,3 @@ "main": "dist/index.js", | ||
"hooks": { | ||
"pre-push": "npm run test", | ||
"pre-push": "npm run test && npm run build", | ||
"pre-commit": "lint-staged" | ||
@@ -57,0 +57,0 @@ } |
@@ -18,3 +18,3 @@ /** | ||
import { Transform } from './types'; | ||
import { OutputOptions } from 'rollup'; | ||
import { ModuleFormat, OutputOptions } from 'rollup'; | ||
import { CompileOptions } from 'google-closure-compiler'; | ||
@@ -24,2 +24,12 @@ import { sync } from 'temp-write'; | ||
/** | ||
* Checks if output format is ESM | ||
* @param format | ||
* @return boolean | ||
*/ | ||
export const isESMFormat = (format?: ModuleFormat | 'esm'): boolean => { | ||
// TODO: remove `| 'esm'` when rollup upgrades its typings | ||
return format === 'esm' || format === 'es'; | ||
}; | ||
/** | ||
* Generate default Closure Compiler CompileOptions an author can override if they wish. | ||
@@ -49,3 +59,3 @@ * These must be derived from configuration or input sources. | ||
language_out: 'NO_TRANSPILE', | ||
assume_function_wrapper: options.format === 'es' ? true : false, | ||
assume_function_wrapper: isESMFormat(options.format) ? true : false, | ||
warning_level: 'QUIET', | ||
@@ -52,0 +62,0 @@ externs, |
@@ -20,2 +20,3 @@ /** | ||
import { NamedDeclaration, DefaultDeclaration } from './parsing-utilities'; | ||
import { isESMFormat } from '../options'; | ||
import { | ||
@@ -34,3 +35,3 @@ ExportNameToClosureMapping, | ||
* @fileoverview Externs built via derived configuration from Rollup or input code. | ||
* This extern contains top level exported members. | ||
* This extern contains top level exported members. | ||
* @externs | ||
@@ -41,3 +42,3 @@ */ | ||
/** | ||
* This Transform will apply only if the Rollup configuration is for 'es' output. | ||
* This Transform will apply only if the Rollup configuration is for 'esm' output. | ||
* | ||
@@ -54,3 +55,3 @@ * In order to preserve the export statements: | ||
let content = HEADER; | ||
if (options.format === 'es') { | ||
if (isESMFormat(options.format)) { | ||
Object.keys(this.exported).forEach(key => { | ||
@@ -130,3 +131,3 @@ content += `window['${key}'] = ${key};\n`; | ||
); | ||
} else if (this.outputOptions.format === 'es') { | ||
} else if (isESMFormat(this.outputOptions.format)) { | ||
Object.keys(this.exported).forEach(key => { | ||
@@ -155,3 +156,3 @@ code += `\nwindow['${key}'] = ${key}`; | ||
); | ||
} else if (this.outputOptions.format === 'es') { | ||
} else if (isESMFormat(this.outputOptions.format)) { | ||
const exportedConstants: Array<string> = []; | ||
@@ -158,0 +159,0 @@ |
@@ -18,2 +18,3 @@ /** | ||
import { Transform } from '../types'; | ||
import { isESMFormat } from '../options'; | ||
import { TransformSourceDescription } from 'rollup'; | ||
@@ -37,3 +38,3 @@ | ||
); | ||
} else if (this.outputOptions.format === 'es' && code.startsWith(STRICT_MODE_DECLARATION)) { | ||
} else if (isESMFormat(this.outputOptions.format) && code.startsWith(STRICT_MODE_DECLARATION)) { | ||
// This will only remove the top level 'use strict' directive since we cannot | ||
@@ -40,0 +41,0 @@ // be certain source does not contain strings with the intended content. |
@@ -18,3 +18,3 @@ /** | ||
import test from 'ava'; | ||
import compiler from '../../transpile/index.js'; | ||
import compiler from '../../transpile/index'; | ||
import { rollup } from 'rollup'; | ||
@@ -27,16 +27,21 @@ import * as fs from 'fs'; | ||
test('esm does minify', async t => { | ||
const source = await readFile(join('test/esmodules/fixtures/esm.js'), 'utf8'); | ||
const compilerBundle = await rollup({ | ||
input: 'test/esmodules/fixtures/esm.js', | ||
plugins: [compiler()], | ||
const createTests = format => { | ||
test(`${format} - does minify`, async t => { | ||
const source = await readFile(join('test/esmodules/fixtures/esm.js'), 'utf8'); | ||
const compilerBundle = await rollup({ | ||
input: 'test/esmodules/fixtures/esm.js', | ||
plugins: [compiler()], | ||
}); | ||
const compilerResults = await compilerBundle.generate({ | ||
format, | ||
sourcemap: true, | ||
}); | ||
t.truthy(compilerResults.code.length < source.length); | ||
}); | ||
const compilerResults = await compilerBundle.generate({ | ||
format: 'es', | ||
sourcemap: true, | ||
}); | ||
} | ||
t.truthy(compilerResults.code.length < source.length); | ||
}); | ||
createTests('esm'); | ||
createTests('es'); | ||
// TODO(KB): Tests verifying exported code contains the correct exported members via acorn AST parse. |
@@ -26,45 +26,50 @@ /** | ||
async function input(input) { | ||
const bundle = await rollup.rollup({ | ||
input: `test/esmodules/fixtures/${input}.js`, | ||
plugins: [compiler()], | ||
}); | ||
const createTests = format => { | ||
async function input(input) { | ||
const bundle = await rollup.rollup({ | ||
input: `test/esmodules/fixtures/${input}.js`, | ||
plugins: [compiler()], | ||
}); | ||
return { | ||
minified: await readFile(join(`test/esmodules/fixtures/${input}.minified.js`), 'utf8'), | ||
code: (await bundle.generate({ | ||
format: 'es', | ||
sourcemap: true, | ||
})).code, | ||
}; | ||
} | ||
return { | ||
minified: await readFile(join(`test/esmodules/fixtures/${input}.minified.js`), 'utf8'), | ||
code: (await bundle.generate({ | ||
format, | ||
sourcemap: true, | ||
})).code, | ||
}; | ||
} | ||
test('input with import exports the only exported function', async t => { | ||
const { minified, code } = await input('importer'); | ||
test(`${format} - input with import exports the only exported function`, async t => { | ||
const { minified, code } = await input('importer'); | ||
t.is(code, minified); | ||
}); | ||
t.is(code, minified); | ||
}); | ||
test('export default named function exports the default named function', async t => { | ||
const { minified, code } = await input('export-default'); | ||
test(`${format} - export default named function exports the default named function`, async t => { | ||
const { minified, code } = await input('export-default'); | ||
t.is(code, minified); | ||
}); | ||
t.is(code, minified); | ||
}); | ||
test('export const values exports the const values', async t => { | ||
const { minified, code } = await input('export-const'); | ||
test(`${format} - export const values exports the const values`, async t => { | ||
const { minified, code } = await input('export-const'); | ||
t.is(code, minified); | ||
}); | ||
t.is(code, minified); | ||
}); | ||
test('export class exports the class', async t => { | ||
const { minified, code } = await input('export-class'); | ||
test(`${format} - export class exports the class`, async t => { | ||
const { minified, code } = await input('export-class'); | ||
t.is(code, minified); | ||
}); | ||
t.is(code, minified); | ||
}); | ||
test('export default class exports the class', async t => { | ||
const { minified, code } = await input('export-default-class'); | ||
test(`${format} - export default class exports the class`, async t => { | ||
const { minified, code } = await input('export-default-class'); | ||
t.is(code, minified); | ||
}); | ||
t.is(code, minified); | ||
}); | ||
} | ||
createTests('esm'); | ||
createTests('es'); |
334893
8654