From e85626ea02836d753e97ae3ee3dceeb0d2e0d650 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 5 Jun 2016 12:10:55 -0400 Subject: [PATCH] options.preferConst to use const instead of var when creating statements (#653) --- src/Bundle.js | 2 ++ src/Declaration.js | 2 +- src/Module.js | 2 +- src/finalisers/cjs.js | 10 ++++++---- src/finalisers/iife.js | 2 +- src/finalisers/shared/getInteropBlock.js | 2 +- src/rollup.js | 1 + test/form/prefer-const/_config.js | 7 +++++++ test/form/prefer-const/_expected/amd.js | 18 ++++++++++++++++++ test/form/prefer-const/_expected/cjs.js | 20 ++++++++++++++++++++ test/form/prefer-const/_expected/es6.js | 18 ++++++++++++++++++ test/form/prefer-const/_expected/iife.js | 19 +++++++++++++++++++ test/form/prefer-const/_expected/umd.js | 22 ++++++++++++++++++++++ test/form/prefer-const/main.js | 9 +++++++++ test/form/prefer-const/namespace.js | 2 ++ test/test.js | 2 +- 16 files changed, 129 insertions(+), 9 deletions(-) create mode 100644 test/form/prefer-const/_config.js create mode 100644 test/form/prefer-const/_expected/amd.js create mode 100644 test/form/prefer-const/_expected/cjs.js create mode 100644 test/form/prefer-const/_expected/es6.js create mode 100644 test/form/prefer-const/_expected/iife.js create mode 100644 test/form/prefer-const/_expected/umd.js create mode 100644 test/form/prefer-const/main.js create mode 100644 test/form/prefer-const/namespace.js diff --git a/src/Bundle.js b/src/Bundle.js index fb160c0..95c0d10 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -73,6 +73,8 @@ export default class Bundle { // TODO strictly speaking, this only applies with non-ES6, non-default-only bundles [ 'module', 'exports', '_interopDefault' ].forEach( global => this.assumedGlobals[ global ] = true ); + + this.varOrConst = options.preferConst ? 'const' : 'var'; } build () { diff --git a/src/Declaration.js b/src/Declaration.js index 0c8fd1e..a8e192a 100644 --- a/src/Declaration.js +++ b/src/Declaration.js @@ -241,7 +241,7 @@ export class SyntheticNamespaceDeclaration { return `${indentString}${name}: ${original.render()}`; }); - return `var ${this.render()} = Object.freeze({\n${members.join( ',\n' )}\n});\n\n`; + return `${this.module.bundle.varOrConst} ${this.render()} = Object.freeze({\n${members.join( ',\n' )}\n});\n\n`; } render () { diff --git a/src/Module.js b/src/Module.js index 4f68ab7..175ecd5 100644 --- a/src/Module.js +++ b/src/Module.js @@ -592,7 +592,7 @@ export default class Module { if ( statement.node.declaration.type === 'FunctionExpression' ) { magicString.overwrite( statement.node.start, statement.node.declaration.start + 8, `function ${defaultName}` ); } else { - magicString.overwrite( statement.node.start, statement.node.declaration.start, `var ${defaultName} = ` ); + magicString.overwrite( statement.node.start, statement.node.declaration.start, `${this.bundle.varOrConst} ${defaultName} = ` ); } } diff --git a/src/finalisers/cjs.js b/src/finalisers/cjs.js index 07adf72..b921429 100644 --- a/src/finalisers/cjs.js +++ b/src/finalisers/cjs.js @@ -9,18 +9,20 @@ export default function cjs ( bundle, magicString, { exportMode }, options ) { intro += `function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }\n\n`; } + const varOrConst = bundle.varOrConst; + // TODO handle empty imports, once they're supported const importBlock = bundle.externalModules .map( module => { if ( module.declarations.default ) { if (module.exportsNames) { - return `var ${module.name} = require('${module.id}');` + - `\nvar ${module.name}__default = _interopDefault(${module.name});`; + return `${varOrConst} ${module.name} = require('${module.id}');` + + `\n${varOrConst} ${module.name}__default = _interopDefault(${module.name});`; } else { - return `var ${module.name} = _interopDefault(require('${module.id}'));`; + return `${varOrConst} ${module.name} = _interopDefault(require('${module.id}'));`; } } else { - return `var ${module.name} = require('${module.id}');`; + return `${varOrConst} ${module.name} = require('${module.id}');`; } }) .join( '\n' ); diff --git a/src/finalisers/iife.js b/src/finalisers/iife.js index 1d4dfb2..adb7019 100644 --- a/src/finalisers/iife.js +++ b/src/finalisers/iife.js @@ -41,7 +41,7 @@ export default function iife ( bundle, magicString, { exportMode, indentString } let outro = `\n\n}(${dependencies}));`; if ( exportMode === 'default' ) { - intro = ( isNamespaced ? `this.` : `var ` ) + `${name} = ${intro}`; + intro = ( isNamespaced ? `this.` : `${bundle.varOrConst} ` ) + `${name} = ${intro}`; } if ( isNamespaced ) { diff --git a/src/finalisers/shared/getInteropBlock.js b/src/finalisers/shared/getInteropBlock.js index e0e2617..a747d82 100644 --- a/src/finalisers/shared/getInteropBlock.js +++ b/src/finalisers/shared/getInteropBlock.js @@ -3,7 +3,7 @@ export default function getInteropBlock ( bundle ) { .map( module => { return module.declarations.default ? ( module.exportsNames ? - `var ${module.name}__default = 'default' in ${module.name} ? ${module.name}['default'] : ${module.name};` : + `${bundle.varOrConst} ${module.name}__default = 'default' in ${module.name} ? ${module.name}['default'] : ${module.name};` : `${module.name} = 'default' in ${module.name} ? ${module.name}['default'] : ${module.name};` ) : null; }) diff --git a/src/rollup.js b/src/rollup.js index 490fe72..77a97bd 100644 --- a/src/rollup.js +++ b/src/rollup.js @@ -25,6 +25,7 @@ const ALLOWED_KEYS = [ 'onwarn', 'outro', 'plugins', + 'preferConst', 'sourceMap', 'treeshake', 'useStrict' diff --git a/test/form/prefer-const/_config.js b/test/form/prefer-const/_config.js new file mode 100644 index 0000000..ebb4828 --- /dev/null +++ b/test/form/prefer-const/_config.js @@ -0,0 +1,7 @@ +module.exports = { + description: 'uses const instead of var if specified (#653)', + options: { + preferConst: true, + moduleName: 'myBundle' + } +}; diff --git a/test/form/prefer-const/_expected/amd.js b/test/form/prefer-const/_expected/amd.js new file mode 100644 index 0000000..a89dacd --- /dev/null +++ b/test/form/prefer-const/_expected/amd.js @@ -0,0 +1,18 @@ +define(['external', 'other', 'another'], function (external, other, another) { 'use strict'; + + const a = 1; + const b = 2; + + + const namespace = Object.freeze({ + a: a, + b: b + }); + + console.log( Object.keys( namespace ) ); + + const main = 42; + + return main; + +}); diff --git a/test/form/prefer-const/_expected/cjs.js b/test/form/prefer-const/_expected/cjs.js new file mode 100644 index 0000000..5c2e4da --- /dev/null +++ b/test/form/prefer-const/_expected/cjs.js @@ -0,0 +1,20 @@ +'use strict'; + +const external = require('external'); +const other = require('other'); +const another = require('another'); + +const a = 1; +const b = 2; + + +const namespace = Object.freeze({ + a: a, + b: b +}); + +console.log( Object.keys( namespace ) ); + +const main = 42; + +module.exports = main; diff --git a/test/form/prefer-const/_expected/es6.js b/test/form/prefer-const/_expected/es6.js new file mode 100644 index 0000000..8f5a5c9 --- /dev/null +++ b/test/form/prefer-const/_expected/es6.js @@ -0,0 +1,18 @@ +import 'external'; +import 'other'; +import 'another'; + +const a = 1; +const b = 2; + + +const namespace = Object.freeze({ + a: a, + b: b +}); + +console.log( Object.keys( namespace ) ); + +const main = 42; + +export default main; diff --git a/test/form/prefer-const/_expected/iife.js b/test/form/prefer-const/_expected/iife.js new file mode 100644 index 0000000..9c66729 --- /dev/null +++ b/test/form/prefer-const/_expected/iife.js @@ -0,0 +1,19 @@ +const myBundle = (function (external,other,another) { + 'use strict'; + + const a = 1; + const b = 2; + + + const namespace = Object.freeze({ + a: a, + b: b + }); + + console.log( Object.keys( namespace ) ); + + const main = 42; + + return main; + +}(external,other,another)); diff --git a/test/form/prefer-const/_expected/umd.js b/test/form/prefer-const/_expected/umd.js new file mode 100644 index 0000000..0c54878 --- /dev/null +++ b/test/form/prefer-const/_expected/umd.js @@ -0,0 +1,22 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('external'), require('other'), require('another')) : + typeof define === 'function' && define.amd ? define(['external', 'other', 'another'], factory) : + (global.myBundle = factory(global.external,global.other,global.another)); +}(this, function (external,other,another) { 'use strict'; + + const a = 1; + const b = 2; + + + const namespace = Object.freeze({ + a: a, + b: b + }); + + console.log( Object.keys( namespace ) ); + + const main = 42; + + return main; + +})); diff --git a/test/form/prefer-const/main.js b/test/form/prefer-const/main.js new file mode 100644 index 0000000..e8cc563 --- /dev/null +++ b/test/form/prefer-const/main.js @@ -0,0 +1,9 @@ +import external from 'external'; +import a from 'other'; +import { b } from 'other'; +import { another } from 'another'; +import * as namespace from './namespace.js'; + +console.log( Object.keys( namespace ) ); + +export default 42; diff --git a/test/form/prefer-const/namespace.js b/test/form/prefer-const/namespace.js new file mode 100644 index 0000000..72ab60e --- /dev/null +++ b/test/form/prefer-const/namespace.js @@ -0,0 +1,2 @@ +export const a = 1; +export const b = 2; diff --git a/test/test.js b/test/test.js index 22d4bce..22239fe 100644 --- a/test/test.js +++ b/test/test.js @@ -76,7 +76,7 @@ describe( 'rollup', function () { return rollup.rollup({ entry: 'x', plUgins: [] }).then( function () { throw new Error( 'Missing expected error' ); }, function ( err ) { - assert.equal( err.message, 'Unexpected key \'plUgins\' found, expected one of: banner, dest, entry, exports, external, footer, format, globals, indent, intro, moduleId, moduleName, noConflict, onwarn, outro, plugins, sourceMap, treeshake, useStrict' ); + assert.equal( err.message, 'Unexpected key \'plUgins\' found, expected one of: banner, dest, entry, exports, external, footer, format, globals, indent, intro, moduleId, moduleName, noConflict, onwarn, outro, plugins, preferConst, sourceMap, treeshake, useStrict' ); }); }); });