├── .gitignore ├── .travis.yml ├── index.js ├── package.json ├── readme.md └── test └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | node_modules/ 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - stable 5 | - 6 6 | - 5 7 | - 4 8 | script: 9 | - npm test 10 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created at 16/5/18. 3 | * @Author Ling. 4 | * @Email i@zeroling.com 5 | */ 6 | 'use strict' 7 | const babylon = require('babylon') 8 | 9 | module.exports = (babel) => { 10 | const t = babel.types 11 | // cache for performance 12 | const parseMap = {} 13 | 14 | return { 15 | visitor: { 16 | Identifier(path, state) { 17 | if (path.parent.type === 'MemberExpression') { 18 | return; 19 | } 20 | if (path.parent.type === 'ClassMethod') { 21 | return; 22 | } 23 | if (path.isPure()) { 24 | return; 25 | } 26 | if (!state.opts.hasOwnProperty(path.node.name)) { 27 | return; 28 | } 29 | let replacementDescriptor = state.opts[path.node.name] 30 | if (replacementDescriptor === undefined || replacementDescriptor === null) { 31 | replacementDescriptor = t.identifier(String(replacementDescriptor)) 32 | } 33 | 34 | const type = typeof replacementDescriptor 35 | if (type === 'string' || type === 'boolean') { 36 | replacementDescriptor = { 37 | type: type, 38 | replacement: replacementDescriptor 39 | } 40 | } else if (t.isNode(replacementDescriptor)) { 41 | replacementDescriptor = { 42 | type: 'node', 43 | replacement: replacementDescriptor 44 | } 45 | } else if (type === 'object' 46 | && replacementDescriptor.type === 'node' 47 | && typeof replacementDescriptor.replacement === 'string') { 48 | replacementDescriptor.replacement = parseMap[replacementDescriptor.replacement] 49 | ? parseMap[replacementDescriptor.replacement] 50 | : babylon.parseExpression(replacementDescriptor.replacement) 51 | } 52 | 53 | const replacement = replacementDescriptor.replacement 54 | switch (replacementDescriptor.type) { 55 | case 'boolean': 56 | path.replaceWith(t.booleanLiteral(replacement)) 57 | break 58 | case 'node': 59 | if (t.isNode(replacement)) { 60 | path.replaceWith(replacement) 61 | } 62 | break 63 | default: 64 | // treat as string 65 | const str = String(replacement) 66 | path.replaceWith(t.stringLiteral(str)) 67 | break 68 | } 69 | } 70 | } 71 | } 72 | }; 73 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "babel-plugin-inline-replace-variables", 3 | "version": "1.3.1", 4 | "description": "babel plugin to inline replace variables", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "mocha -u bdd" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/wssgcg1213/babel-plugin-inline-replace-variables" 12 | }, 13 | "keywords": [ 14 | "babel", 15 | "plugin", 16 | "inline", 17 | "replace", 18 | "variables" 19 | ], 20 | "author": "Ling.", 21 | "license": "MIT", 22 | "dependencies": { 23 | "babylon": "^6.17.0" 24 | }, 25 | "devDependencies": { 26 | "babel-core": "^6.8.0", 27 | "mocha": "^2.4.5", 28 | "should": "^11.2.0" 29 | }, 30 | "engines": { 31 | "node": ">= 4" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # babel-plugin-inline-replace-variables 4 | 5 | [![Build Status](https://travis-ci.org/wssgcg1213/babel-plugin-inline-replace-variables.svg?branch=master)](https://travis-ci.org/wssgcg1213/babel-plugin-inline-replace-variables) 6 | 7 | It replace an Identifier to a literial (LVal), if you want to transfrom a identifier to another identifier, you can see: [babel-plugin-replace-identifiers](https://github.com/wssgcg1213/babel-plugin-replace-identifiers) 8 | ## Usage 9 | 10 | ```bash 11 | npm i babel-plugin-inline-replace-variables --save-dev 12 | ``` 13 | 14 | configure in .babelrc(should transfer to json format) or any babel queries: 15 | ```javascript 16 | { 17 | plugins: [ 18 | ['inline-replace-variables', { 19 | "__SERVER__": true, 20 | "__VERSION__": "v1.2.3" 21 | }] 22 | ] 23 | } 24 | ``` 25 | 26 | #### EFFECT: 27 | 28 | ```javascript 29 | if (__SERVER__) { 30 | console.log('this is server, version: %s', __VERSION__) 31 | } else { 32 | alert('this is browser') 33 | } 34 | ``` 35 | 36 | will be transformed to 37 | 38 | ``` 39 | if (true) { 40 | console.log('this is server, version: %s', "v1.2.3") 41 | } else { 42 | alert('this is browser') 43 | } 44 | ``` 45 | 46 | ### Support Replace With Expression: 47 | 48 | ```js 49 | { 50 | plugins: [ 51 | ['inline-replace-variables', { 52 | "__TYPE__": { 53 | type: 'node', 54 | replacement: 'process.env.NODE_ENV' 55 | } 56 | }] 57 | ] 58 | } 59 | ``` 60 | 61 | #### EFFECT 62 | ```js 63 | if (__TYPE__) { 64 | // code 65 | } 66 | ``` 67 | 68 | to 69 | 70 | ```js 71 | if (process.env.NODE_ENV) { 72 | // code 73 | } 74 | ``` 75 | 76 | 77 | 78 | ### Also support babel AST Node 79 | 80 | ```js 81 | const t = require('babel-types'); 82 | const nodeEnv = t.memberExpression(t.memberExpression(t.identifier('process'), t.identifier('env')), t.identifier('NODE_ENV')); 83 | 84 | { 85 | plugins: [ 86 | ['inline-replace-variables', { 87 | "__TYPE__": nodeEnv 88 | }] 89 | ] 90 | } 91 | ``` 92 | 93 | #### EFFECT 94 | 95 | The effect is the same above. 96 | 97 | 98 | 99 | #### tip: 100 | 101 | Version 1.0.1 fix the misspelling of 'varibles' to 'variables' 102 | 103 | so `babel-plugin-inline-replace-varibles` is deprecated, you should instead it of `babel-plugin-inline-replace-variables` 104 | 105 | 106 | 107 | Authors: https://github.com/wssgcg1213, https://github.com/rtsao 108 | 109 | 110 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created at 16/5/15. 3 | * @Author Ling. 4 | * @Email i@zeroling.com 5 | */ 6 | const babel = require('babel-core'); 7 | const babylon = require('babylon'); 8 | require('should'); 9 | const plugin = require('../'); 10 | 11 | describe('simple', () => { 12 | describe(`transform`, () => { 13 | it(`__SERVER__ should be replaced to true`, () => { 14 | babel.transform(` 15 | if (__SERVER__) { 16 | console.log('this is server, version: %s', __VERSION__) 17 | } else { 18 | alert('this is browser') 19 | } 20 | `, { 21 | plugins: [[plugin, { 22 | __SERVER__: true, 23 | __VERSION__: "v1.2.3" 24 | }]] 25 | }).code 26 | .should.be.equal(` 27 | if (true) { 28 | console.log('this is server, version: %s', 'v1.2.3'); 29 | } else { 30 | alert('this is browser'); 31 | }`) 32 | }); 33 | }); 34 | 35 | }); 36 | 37 | describe('simple', () => { 38 | describe(`transform`, () => { 39 | it(`__SERVER__ should be replaced to false`, () => { 40 | babel.transform(` 41 | if (__SERVER__) { 42 | console.log('this is server, version: %s', __VERSION__) 43 | } else { 44 | alert('this is browser') 45 | } 46 | `, { 47 | plugins: [[plugin, { 48 | __SERVER__: false, 49 | __VERSION__: "v1.2.3" 50 | }]] 51 | }).code 52 | .should.be.equal(` 53 | if (false) { 54 | console.log('this is server, version: %s', 'v1.2.3'); 55 | } else { 56 | alert('this is browser'); 57 | }`) 58 | }); 59 | }); 60 | 61 | }); 62 | 63 | 64 | 65 | describe('member expression', () => { 66 | describe(`transform`, () => { 67 | it(`__SERVER__ should NOT be replaced to true`, () => { 68 | babel.transform(` 69 | if (foo.bar.__SERVER__) { 70 | console.log('this is server, version: %s', __VERSION__) 71 | } else { 72 | alert('this is browser') 73 | } 74 | `, { 75 | plugins: [[plugin, { 76 | __SERVER__: true, 77 | __VERSION__: "v1.2.3" 78 | }]] 79 | }).code 80 | .should.be.equal(` 81 | if (foo.bar.__SERVER__) { 82 | console.log('this is server, version: %s', 'v1.2.3'); 83 | } else { 84 | alert('this is browser'); 85 | }`) 86 | }); 87 | }); 88 | 89 | }); 90 | 91 | describe('non-globals', () => { 92 | describe(`transform`, () => { 93 | it(`__SERVER__ should NOT be replaced to true`, () => { 94 | babel.transform(` 95 | function foo(__SERVER__) { 96 | console.log('this is a normal argument', __SERVER__) 97 | } 98 | `, { 99 | plugins: [[plugin, { 100 | __SERVER__: true, 101 | __VERSION__: "v1.2.3" 102 | }]] 103 | }).code 104 | .should.be.equal(` 105 | function foo(__SERVER__) { 106 | console.log('this is a normal argument', __SERVER__); 107 | }`) 108 | }); 109 | }); 110 | 111 | }); 112 | 113 | describe('ignore class methods', () => { 114 | describe(`transform`, () => { 115 | it(`__SERVER__ should NOT be replaced`, () => { 116 | babel.transform(` 117 | export default class Hello { 118 | __SERVER__(foo) { 119 | this.foo = foo; 120 | } 121 | } 122 | `, { 123 | plugins: [[plugin, { 124 | __SERVER__: true, 125 | __VERSION__: "v1.2.3" 126 | }]] 127 | }).code 128 | .should.be.equal(` 129 | export default class Hello { 130 | __SERVER__(foo) { 131 | this.foo = foo; 132 | } 133 | }`) 134 | }); 135 | 136 | }); 137 | 138 | }); 139 | 140 | describe('object own properties', () => { 141 | describe(`transform`, () => { 142 | it(`only own properties should be replaced`, () => { 143 | babel.transform(` 144 | var foo = constructor; 145 | var bar = isPrototypeOf; 146 | var baz = __SERVER__; 147 | `, { 148 | plugins: [[plugin, { 149 | __SERVER__: true, 150 | __VERSION__: "v1.2.3" 151 | }]] 152 | }).code 153 | .should.be.equal(` 154 | var foo = constructor; 155 | var bar = isPrototypeOf; 156 | var baz = true;`) 157 | }); 158 | 159 | }); 160 | }); 161 | 162 | describe('support node replacement', () => { 163 | it('__DEV__ should be replaced by process.env.NODE_ENV', () => { 164 | babel.transform(` 165 | if (__DEV__) { 166 | console.log('this is dev'); 167 | } else { 168 | console.log('this is prod'); 169 | } 170 | `, { 171 | plugins: [[plugin, { 172 | __DEV__: { 173 | type: 'node', 174 | replacement: 'process.env.NODE_ENV' 175 | } 176 | }]] 177 | }).code.should.be.equal(` 178 | if (process.env.NODE_ENV) { 179 | console.log('this is dev'); 180 | } else { 181 | console.log('this is prod'); 182 | }`); 183 | }); 184 | 185 | it('__DEV__ should be replaced by process.env.NODE_ENV', () => { 186 | babel.transform(` 187 | if (__DEV__) { 188 | console.log('this is dev'); 189 | } else { 190 | console.log('this is prod'); 191 | } 192 | `, { 193 | plugins: [[plugin, { 194 | __DEV__: babylon.parseExpression('process.env.NODE_ENV') 195 | }]] 196 | }).code.should.be.equal(` 197 | if (process.env.NODE_ENV) { 198 | console.log('this is dev'); 199 | } else { 200 | console.log('this is prod'); 201 | }`); 202 | }); 203 | }); 204 | 205 | describe('support false value replacement', () => { 206 | it('__DEV__ should be replaced by false', () => { 207 | babel.transform(` 208 | if (__DEV__) { 209 | console.log('this is dev'); 210 | } else { 211 | console.log('this is prod'); 212 | } 213 | `, { 214 | plugins: [[plugin, { 215 | __DEV__: false 216 | }]] 217 | }).code.should.be.equal(` 218 | if (false) { 219 | console.log('this is dev'); 220 | } else { 221 | console.log('this is prod'); 222 | }`); 223 | }); 224 | 225 | it('__DEV__ should be replaced by undefined', () => { 226 | babel.transform(` 227 | if (__DEV__) { 228 | console.log('this is dev'); 229 | } else { 230 | console.log('this is prod'); 231 | } 232 | `, { 233 | plugins: [[plugin, { 234 | __DEV__: undefined 235 | }]] 236 | }).code.should.be.equal(` 237 | if (undefined) { 238 | console.log('this is dev'); 239 | } else { 240 | console.log('this is prod'); 241 | }`); 242 | }); 243 | 244 | it('__DEV__ should be replaced by null', () => { 245 | babel.transform(` 246 | if (__DEV__) { 247 | console.log('this is dev'); 248 | } else { 249 | console.log('this is prod'); 250 | } 251 | `, { 252 | plugins: [[plugin, { 253 | __DEV__: null 254 | }]] 255 | }).code.should.be.equal(` 256 | if (null) { 257 | console.log('this is dev'); 258 | } else { 259 | console.log('this is prod'); 260 | }`); 261 | }); 262 | }); 263 | --------------------------------------------------------------------------------