├── .gitignore ├── .jshintrc ├── .travis.yml ├── LICENSE ├── README.md ├── example ├── build.js ├── build.sh └── sample.js ├── index.js ├── package.json └── test └── varify.js /.gitignore: -------------------------------------------------------------------------------- 1 | lib-cov 2 | *.seed 3 | *.log 4 | *.csv 5 | *.dat 6 | *.out 7 | *.pid 8 | *.gz 9 | 10 | pids 11 | logs 12 | results 13 | 14 | npm-debug.log 15 | node_modules 16 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "laxcomma" : true 3 | , "laxbreak" : true 4 | , "sub" : true 5 | , "onecase" : true 6 | , "node" : true 7 | , "expr" : true 8 | , "strict" : false 9 | , "es5" : true 10 | , "esnext" : true 11 | , "validthis": true 12 | } 13 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.8" 4 | - "0.10" 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2013 Thorsten Lorenz. 2 | All rights reserved. 3 | 4 | Permission is hereby granted, free of charge, to any person 5 | obtaining a copy of this software and associated documentation 6 | files (the "Software"), to deal in the Software without 7 | restriction, including without limitation the rights to use, 8 | copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the 10 | Software is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # varify [![build status](https://secure.travis-ci.org/thlorenz/varify.png)](http://travis-ci.org/thlorenz/varify) 2 | 3 | browserify transform that converts all const assignments to var assignments. 4 | 5 | npm install varify 6 | 7 | ## Why? 8 | 9 | So you can get the benefits of immutable variables with help of lint tools while staying compatible with older browsers 10 | that have no `const`. 11 | 12 | ## Warning 13 | 14 | The real `const` is block scoped, however when replaced with `var` this feature is lost. So only use varify if you can 15 | do without block scope and are only looking for some immutability support that gets compiled out for compatibility. 16 | 17 | If you are after block scope, have a look at [def.js](https://github.com/olov/defs) which provides 18 | [limited](https://github.com/olov/defs#loop-closures-limitation) support for that. 19 | 20 | ## Example 21 | 22 | Given this JavaScript: 23 | 24 | ```js 25 | const a = 1; 26 | 27 | var keep = { const: 1 }; 28 | keep.const = 2; 29 | 30 | const foo = function () { 31 | console.log('some const s should be left unchanged'); 32 | }; 33 | ``` 34 | 35 | Running browserify with varify transform: 36 | 37 | ```js 38 | require('browserify')() 39 | .transform(require('varify')) 40 | .add(__dirname + '/sample.js') 41 | .bundle() 42 | .pipe(process.stdout); 43 | ``` 44 | 45 | Outputs: 46 | 47 | ```js 48 | var a = 1; 49 | 50 | var keep = { const: 1 }; 51 | keep.const = 2; 52 | 53 | var foo = function () { 54 | console.log('some const s should be left unchanged'); 55 | }; 56 | ``` 57 | 58 | ## Usage from Commandline 59 | 60 | browserify -t varify sample.js > bundle.js 61 | -------------------------------------------------------------------------------- /example/build.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var browserify = require('browserify'); 3 | 4 | browserify() 5 | .transform(require('..')) 6 | .add(__dirname + '/sample.js') 7 | .bundle() 8 | .pipe(process.stdout); 9 | -------------------------------------------------------------------------------- /example/build.sh: -------------------------------------------------------------------------------- 1 | browserify sample.js -t varify 2 | -------------------------------------------------------------------------------- /example/sample.js: -------------------------------------------------------------------------------- 1 | // sample start 2 | // this should be changed 3 | const a = 1; 4 | 5 | // below two shouldn't 6 | var keep = { const: 1 }; 7 | keep.const = 2; 8 | 9 | // only function assignment should be changed 10 | const foo = function () { 11 | console.log('cannot change me'); 12 | console.log('some const s should be left unchanged'); 13 | }; 14 | // sample end 15 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var through = require('through') 4 | , redeyed = require('redeyed') 5 | , path = require('path'); 6 | 7 | var config = { 8 | Keyword: { 9 | const: function (tokenString, info) { 10 | var idx = info.tokenIndex 11 | , tokens = info.tokens 12 | , nextToken = tokens[idx + 1]; 13 | 14 | return nextToken && nextToken.type === 'Identifier' ? 'var' : tokenString; 15 | } 16 | } 17 | }; 18 | 19 | module.exports = function (file) { 20 | var data = ''; 21 | function ondata (d) { data += d; } 22 | function onend() { 23 | try { 24 | if (!/const\s/.test(data)) return this.queue(data); 25 | this.queue(redeyed(data, config).code); 26 | } catch (e) { 27 | console.error('unable to remove consts from ' + file); 28 | console.error(e); 29 | this.queue(data); 30 | } 31 | this.emit('end'); 32 | } 33 | return (path.extname(file) === '.json') 34 | ? through() 35 | : through(ondata, onend); 36 | }; 37 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "varify", 3 | "version": "0.2.0", 4 | "description": "browserify transform that converts all const assignments to var assignments.", 5 | "main": "varify.js", 6 | "scripts": { 7 | "test": "tap test/*.js" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git://github.com/thlorenz/varify.git" 12 | }, 13 | "homepage": "https://github.com/thlorenz/varify", 14 | "dependencies": { 15 | "redeyed": "~1.0.1", 16 | "through": "~2.3.4" 17 | }, 18 | "devDependencies": { 19 | "tap": "~0.4.3", 20 | "browserify": "~2.14.2" 21 | }, 22 | "keywords": [ 23 | "const", 24 | "var", 25 | "es5", 26 | "refactor", 27 | "compatible" 28 | ], 29 | "author": { 30 | "name": "Thorsten Lorenz", 31 | "email": "thlorenz@gmx.de", 32 | "url": "http://thlorenz.com" 33 | }, 34 | "license": "MIT", 35 | "engine": { 36 | "node": ">=0.6" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /test/varify.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | /*jshint asi:true*/ 3 | 4 | var test = require('tap').test 5 | var through = require('through') 6 | var browserify = require('browserify') 7 | 8 | test('replaces all consts that are declare identifiers, but leaves others intact', function (t) { 9 | t.plan(1) 10 | 11 | browserify() 12 | .transform(require('..')) 13 | .add(__dirname + '/../example/sample.js') 14 | .bundle() 15 | .pipe(through(ondata, onend)); 16 | 17 | var data = '' 18 | function ondata(d) { data += d } 19 | function onend() { 20 | var lines = data.split('\n') 21 | var startline = lines.indexOf('// sample start') + 1 22 | , endline = lines.indexOf('// sample end'); 23 | 24 | t.deepEqual( 25 | lines.slice(startline, endline) 26 | , [ "// this should be changed", 27 | "var a = 1;", 28 | "", 29 | "// below two shouldn't", 30 | "var keep = { const: 1 };", 31 | "keep.const = 2;", 32 | "", 33 | "// only function assignment should be changed", 34 | "var foo = function () {", 35 | " console.log('cannot change me');", 36 | " console.log('some const s should be left unchanged');", 37 | "};" ] 38 | ) 39 | } 40 | 41 | }) 42 | --------------------------------------------------------------------------------