├── .editorconfig ├── .eslintignore ├── .eslintrc ├── .gitignore ├── .npmignore ├── .npmrc ├── .travis.yml ├── CHANGELOG.md ├── README.md ├── index.js ├── package.json └── test ├── code.js └── index.test.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | # 编码 7 | charset = utf-8 8 | # 缩进风格 9 | indent_style = space 10 | # 缩进宽度 11 | indent_size = 2 12 | # 换行符 13 | end_of_line = lf 14 | # 文件以空白行结尾 15 | insert_final_newline = true 16 | # 去除行首任意空白字符 17 | trim_trailing_whitespace = true 18 | 19 | [*.md] 20 | insert_final_newline = false 21 | trim_trailing_whitespace = false 22 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | 3 | test/code.js 4 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": "airbnb", 4 | "env": { 5 | "es6": true, 6 | "browser": true, 7 | "node": true, 8 | "jest": true 9 | }, 10 | "plugins": [], 11 | "parserOptions": { 12 | "ecmaVersion": 2018, 13 | "ecmaFeatures": { 14 | "impliedStrict": true 15 | }, 16 | "sourceType": "module" 17 | }, 18 | "rules": { 19 | "comma-dangle": ["error", "only-multiline"], 20 | "semi": 0, 21 | "func-names": 0, 22 | "eqeqeq": 0, 23 | "no-plusplus": 0, 24 | "prefer-destructuring": ["error", { 25 | "array": false, 26 | "object": false 27 | }], 28 | "no-param-reassign": ["error", { 29 | "props": false 30 | }] 31 | } 32 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/node,macos,visualstudiocode 3 | 4 | ### macOS ### 5 | # General 6 | .DS_Store 7 | .AppleDouble 8 | .LSOverride 9 | 10 | # Icon must end with two \r 11 | Icon 12 | 13 | # Thumbnails 14 | ._* 15 | 16 | # Files that might appear in the root of a volume 17 | .DocumentRevisions-V100 18 | .fseventsd 19 | .Spotlight-V100 20 | .TemporaryItems 21 | .Trashes 22 | .VolumeIcon.icns 23 | .com.apple.timemachine.donotpresent 24 | 25 | # Directories potentially created on remote AFP share 26 | .AppleDB 27 | .AppleDesktop 28 | Network Trash Folder 29 | Temporary Items 30 | .apdisk 31 | 32 | ### Node ### 33 | # Logs 34 | logs 35 | *.log 36 | npm-debug.log* 37 | yarn-debug.log* 38 | yarn-error.log* 39 | 40 | # Runtime data 41 | pids 42 | *.pid 43 | *.seed 44 | *.pid.lock 45 | 46 | # Directory for instrumented libs generated by jscoverage/JSCover 47 | lib-cov 48 | 49 | # Coverage directory used by tools like istanbul 50 | coverage 51 | 52 | # nyc test coverage 53 | .nyc_output 54 | 55 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 56 | .grunt 57 | 58 | # Bower dependency directory (https://bower.io/) 59 | bower_components 60 | 61 | # node-waf configuration 62 | .lock-wscript 63 | 64 | # Compiled binary addons (https://nodejs.org/api/addons.html) 65 | build/Release 66 | 67 | # Dependency directories 68 | node_modules/ 69 | jspm_packages/ 70 | 71 | # TypeScript v1 declaration files 72 | typings/ 73 | 74 | # Optional npm cache directory 75 | .npm 76 | 77 | # Optional eslint cache 78 | .eslintcache 79 | 80 | # Optional REPL history 81 | .node_repl_history 82 | 83 | # Output of 'npm pack' 84 | *.tgz 85 | 86 | # Yarn Integrity file 87 | .yarn-integrity 88 | 89 | # dotenv environment variables file 90 | .env 91 | 92 | # parcel-bundler cache (https://parceljs.org/) 93 | .cache 94 | 95 | # next.js build output 96 | .next 97 | 98 | # nuxt.js build output 99 | .nuxt 100 | 101 | # vuepress build output 102 | .vuepress/dist 103 | 104 | # Serverless directories 105 | .serverless 106 | 107 | 108 | ### VisualStudioCode ### 109 | .vscode/* 110 | !.vscode/settings.json 111 | !.vscode/tasks.json 112 | !.vscode/launch.json 113 | !.vscode/extensions.json 114 | 115 | 116 | # End of https://www.gitignore.io/api/node,macos,visualstudiocode 117 | 118 | ## 119 | 120 | dist 121 | package-lock.json 122 | 123 | .vscode 124 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .editorconfig 3 | .eslintignore 4 | .eslintrc 5 | .gitignore 6 | .travis.yml 7 | .npmrc 8 | .npmignore 9 | package-lock.json 10 | test/ 11 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huruji/babel-plugin-no-debugging/fff4438d7fa3b144f2945f99772499669ee37804/.npmrc -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huruji/babel-plugin-no-debugging/fff4438d7fa3b144f2945f99772499669ee37804/.travis.yml -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. 4 | 5 | 6 | ## [1.3.1](https://github.com/huruji/babel-plugin-no-debugging/compare/v1.3.0...v1.3.1) (2018-11-20) 7 | 8 | 9 | 10 | 11 | # 1.3.0 (2018-11-20) 12 | 13 | 14 | ### Features 15 | 16 | * **chain-get:** use as module ([b654e8e](https://github.com/huruji/babel-plugin-no-debugging/commit/b654e8e)) 17 | 18 | 19 | 20 | 21 | ## 1.0.4 (2018-11-18) 22 | 23 | 24 | ### Bug Fixes 25 | 26 | * **README:** 修复文档 ([d2b3d62](https://github.com/huruji/babel-plugin-no-debugging/commit/d2b3d62)) 27 | 28 | 29 | 30 | 31 | ## 1.0.3 (2018-11-18) 32 | 33 | 34 | ### Bug Fixes 35 | 36 | * **自定义debug:** 函数声明的修改 ([331a899](https://github.com/huruji/babel-plugin-no-debugging/commit/331a899)) 37 | * **自定义debugger:** 使用链式chainGet ([f25d342](https://github.com/huruji/babel-plugin-no-debugging/commit/f25d342)) 38 | * **自定义debugger:** 连续声明的处理 ([bb7b15f](https://github.com/huruji/babel-plugin-no-debugging/commit/bb7b15f)) 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # babel-plugin-no-debugging 2 | 上线前去掉调试代码的Babel插件 3 | 4 | ## 安装 5 | 6 | ```js 7 | npm install -D babel-plugin-no-debugging 8 | ``` 9 | 10 | ## 使用 11 | 12 | `.babelrc` 13 | ```js 14 | { 15 | plugins: ["no-debugging"] 16 | } 17 | ``` 18 | 19 | 这个插件默认会移除 `debugger;` 和 `console` 调用。 20 | 21 | 这个插件可以移除 `debugger` 、 `console` 、 `alert` 和 自定义的调试函数调用和定义。自定义的debugger函数常常在不好调试的端环境中使用,如在可抓包环境下发起一个简单请求判断代码是否运行到某个位置 22 | 23 | > 注意:据笔者了解 `alert` 函数调用仍然大量存在于各类管理后台系统中,开启时需要注意。 24 | 25 | 为保证在开发阶段不转换代码,记得将这个插件只配置在发布阶段: 26 | 27 | `.babelrc` 28 | 29 | ```js 30 | { 31 | { 32 | "env": { 33 | "publish": { 34 | "presets": [ 35 | "@babel/preset-env" 36 | ], 37 | "plugins": ["no-debugging"] 38 | } 39 | } 40 | } 41 | ``` 42 | 43 | 在项目的 `package.json` 中配置好 `scripts` 会更加方便: 44 | 45 | ``` 46 | { 47 | "scripts": { 48 | "build": "cross-env BABEL_ENV=publish webpack", 49 | }, 50 | } 51 | ``` 52 | 53 | ## options 54 | 55 | 56 | | Property | Type | Default | Description | 57 | | -------- | ------- | ------- | ------------------------------------------------------- | 58 | | debugger | Boolean | true | 移除断点调试 `debugger;` 代码 | 59 | | console | Boolean | true | 移除 `console` 函数调用 | 60 | | alert | Boolean | null | 移除 `alert` 函数调用 | 61 | | debugFn | String | null | 移除 指定的自定义调试代码函数(包括调试函数声明和调用) | 62 | 63 | 64 | ## 例子 65 | 66 | ### 使用默认配置: 67 | 68 | `.babelrc` 69 | 70 | ```js 71 | { 72 | plugins: [ 73 | [ 74 | "no-debugging" 75 | ] 76 | ] 77 | } 78 | ``` 79 | 80 | 转换前: 81 | 82 | ```js 83 | const a = 12; 84 | const b = 13; 85 | 86 | function add(m, n) { 87 | debugger; 88 | return m + n; 89 | } 90 | 91 | const result = add(a, b); 92 | 93 | console.log(result); 94 | ``` 95 | 96 | 转换后: 97 | 98 | ```js 99 | const a = 12; 100 | const b = 13; 101 | 102 | function add(m, n) { 103 | return m + n; 104 | } 105 | 106 | const result = add(a, b); 107 | 108 | ``` 109 | 110 | ### 自定义配置 111 | 112 | 移除 `alert` 和 自定义的 debugger 函数 113 | 114 | `.babelrc` 115 | 116 | ```js 117 | { 118 | plugins: [ 119 | [ 120 | "no-debugging", 121 | { 122 | alert: true, 123 | debugFn: "requestDebug", 124 | console: false 125 | } 126 | ] 127 | ] 128 | } 129 | ``` 130 | 131 | 转换前: 132 | 133 | ```js 134 | 135 | const a = 12; 136 | const b = 13; 137 | 138 | function requestDebug(name) { 139 | const debugjs = 'https://example.com/debugger.js' 140 | request(`${debugjs}?name=${name}`).then(()=>{ 141 | // your code 142 | }) 143 | } 144 | 145 | function add(m, n) { 146 | debugger; 147 | return m + n; 148 | } 149 | 150 | alert(result); 151 | 152 | const result = add(a, b); 153 | 154 | console.log(result); 155 | 156 | requestDebug(result); 157 | 158 | ``` 159 | 160 | 转换后: 161 | 162 | ```js 163 | const a = 12; 164 | const b = 13; 165 | 166 | 167 | function add(m, n) { 168 | return m + n; 169 | } 170 | 171 | 172 | const result = add(a, b); 173 | 174 | console.log(result); 175 | 176 | ``` -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const chainGet = require('chain-get'); 2 | const defualtOpts = { 3 | debugger: true, 4 | console: true 5 | } 6 | 7 | 8 | const visitor = { 9 | DebuggerStatement(path, state) { 10 | if (state) { 11 | if (typeof state.opts === 'undefined') { 12 | state.opts = defualtOpts; 13 | } 14 | if (typeof state.opts.debugger === 'undefined') { 15 | state.opts.debugger = true; 16 | } 17 | if (state.opts.debugger) { 18 | path.remove(); 19 | } 20 | } 21 | }, 22 | ExpressionStatement(path, state) { 23 | if (state) { 24 | if (typeof state.opts === 'undefined') { 25 | state.opts = defualtOpts; 26 | } 27 | } 28 | if (chainGet(path).node.expression.type() === 'CallExpression' && chainGet(path).node.expression.callee()) { 29 | // remove alert 30 | if (path.node.expression.callee.name === 'alert') { 31 | if (state.opts.alert) { 32 | path.remove() 33 | } 34 | return; 35 | } 36 | 37 | // remove console 38 | if (path.node.expression.callee.type === 'MemberExpression' && chainGet(path).node.expression.callee.object.name() === 'console') { 39 | if (state && state.opts) { 40 | if (typeof state.opts.console === 'undefined') { 41 | state.opts.console = true; 42 | } 43 | } 44 | if (chainGet(state).opts.console()) { 45 | path.remove(); 46 | } 47 | return; 48 | } 49 | 50 | // remove customized debugger function 51 | if (typeof chainGet(state).opts.debugFn() === 'string') { 52 | const fn = state.opts.debugFn; 53 | if (chainGet(path).node.expression.callee.name() === fn) { 54 | path.remove(); 55 | } 56 | } 57 | } 58 | }, 59 | FunctionDeclaration(path, state) { 60 | if (!state || typeof state.opts === 'undefined' || !state.opts.debugFn || typeof state.opts.debugFn !== 'string') return; 61 | if (chainGet(path).node.id.type() === 'Identifier' && path.node.id.name === state.opts.debugFn) { 62 | path.remove(); 63 | } 64 | }, 65 | VariableDeclarator(path, state) { 66 | if (!state || typeof state.opts === 'undefined' || !state.opts.debugFn || typeof state.opts.debugFn !== 'string') return; 67 | const fn = state.opts.debugFn; 68 | if (chainGet(path).node.id.name() === fn) { 69 | if (path.inList) { 70 | path.remove(); 71 | } else { 72 | const parentPath = path.parentPath; 73 | parentPath.remove(); 74 | } 75 | } 76 | } 77 | } 78 | 79 | 80 | module.exports = function () { 81 | return { 82 | visitor 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "babel-plugin-no-debugging", 3 | "version": "1.3.1", 4 | "description": "上线前去掉调试代码的Babel插件", 5 | "main": "index.js", 6 | "scripts": { 7 | "release": "standard-version", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/huruji/babel-plugin-no-debugging.git" 13 | }, 14 | "keywords": [], 15 | "author": "", 16 | "license": "ISC", 17 | "bugs": { 18 | "url": "https://github.com/huruji/babel-plugin-no-debugging/issues" 19 | }, 20 | "homepage": "https://github.com/huruji/babel-plugin-no-debugging#readme", 21 | "devDependencies": { 22 | "@babel/cli": "^7.1.5", 23 | "@babel/core": "^7.1.6", 24 | "@babel/types": "^7.1.6", 25 | "eslint": "^5.9.0", 26 | "eslint-config-airbnb": "^17.1.0", 27 | "eslint-plugin-import": "^2.14.0", 28 | "eslint-plugin-jsx-a11y": "^6.1.2", 29 | "eslint-plugin-react": "^7.11.1", 30 | "standard-version": "^4.4.0" 31 | }, 32 | "dependencies": { 33 | "chain-get": "^1.0.1" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /test/code.js: -------------------------------------------------------------------------------- 1 | const a = 12; 2 | const b = 13; 3 | debugger; 4 | 5 | alert(123); 6 | 7 | // function debug() { 8 | // console.log(123) 9 | // } 10 | 11 | const c = 15, 12 | debug = function () { 13 | console.log(123); 14 | } 15 | 16 | debug(); 17 | 18 | function add(m, n) { 19 | return m + n; 20 | } 21 | add(a, b); 22 | 23 | console.log('end') 24 | -------------------------------------------------------------------------------- /test/index.test.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | const babel = require('@babel/core'); 4 | const noDebuggerPlugin = require('../index'); 5 | 6 | 7 | const code = fs.readFileSync(path.resolve(__dirname, './code.js'), 'utf-8'); 8 | 9 | const result = babel.transform(code, { 10 | plugins: [ 11 | [ 12 | noDebuggerPlugin, 13 | { 14 | // console: true, 15 | // debugFn: 'debug' 16 | alert: true, 17 | console: true 18 | } 19 | ] 20 | ] 21 | }) 22 | 23 | console.log(result.code); 24 | --------------------------------------------------------------------------------