├── .gitignore ├── LICENSE ├── README.md ├── index.js ├── package-lock.json ├── package.json └── test └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | Version 2, December 2004 3 | 4 | Copyright (C) 2018 Rasmus Porsager 5 | 6 | Everyone is permitted to copy and distribute verbatim or modified 7 | copies of this license document, and changing it is allowed as long 8 | as the name is changed. 9 | 10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | 13 | 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![version](https://img.shields.io/npm/v/rollup-plugin-modify.svg)]() [![license](https://img.shields.io/github/license/porsager/rollup-plugin-modify.svg)]() 2 | 3 | # 🔎 `rollup-plugin-modify` 4 | 5 | Modify rollup output with find / replace dynamically. 6 | 7 | ## Usage 8 | 9 | ```bash 10 | npm i rollup-plugin-modify 11 | ``` 12 | 13 | Explicit single using find, replace keys 14 | ```js 15 | import modify from 'rollup-plugin-modify' 16 | 17 | export default { 18 | plugins: [ 19 | modify({ 20 | find: String | RegExp, 21 | replace: String | Function 22 | }) 23 | ] 24 | } 25 | ``` 26 | 27 | Terse multiple using key, value 28 | ``` 29 | import modify from 'rollup-plugin-modify' 30 | 31 | export default { 32 | plugins: [ 33 | modify({ 34 | 'find this text': 'replace with this here', 35 | 'process.env.PORT': 5000 36 | }) 37 | ] 38 | } 39 | ``` 40 | 41 | ### `find: String|RegExp` 42 | 43 | Supply a string or RegExp to find what you are looking for 44 | 45 | ### `replace: String|Function` 46 | 47 | Supply a string to directly replace what you've found, or a function to dynamically modify your findings 48 | 49 | #### Example using String for both find and replace 50 | 51 | ```js 52 | modify({ 53 | find: 'eval', 54 | replace: 'lava' 55 | }) 56 | ``` 57 | 58 | #### Example using RegExp for find and a Function for replace 59 | 60 | ```js 61 | modify({ 62 | find: /svg\((.*?)\)/, 63 | replace: (match, path) => JSON.stringify(fs.readFileSync(path, 'utf8')) 64 | }) 65 | ``` 66 | 67 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const MagicString = require('magic-string') 2 | 3 | const escapeRegExp = x => x.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&') 4 | 5 | module.exports = function modify({ 6 | find, 7 | replace, 8 | sourcemap = true, 9 | ...rest 10 | }) { 11 | const modifiers = [[find, replace], ...Object.entries(rest)] 12 | .filter(x => x[0]) 13 | .map(([find, replace]) => [ 14 | parseFind(find), 15 | replace 16 | ]) 17 | 18 | return { 19 | name: 'modify', 20 | transform: (source, id) => { 21 | if (modifiers.every(x => !x[0].test(source))) 22 | return 23 | 24 | const s = new MagicString(source) 25 | 26 | modifiers.forEach(([find, replace]) => { 27 | find.lastIndex = 0 28 | let match 29 | while ((match = find.exec(source)) !== null) { 30 | s.overwrite( 31 | match.index, 32 | match.index + match[0].length, 33 | typeof replace === 'function' 34 | ? replace.apply(null, match) 35 | : String(replace) 36 | ) 37 | } 38 | 39 | return s 40 | }) 41 | 42 | return { 43 | code: s.toString(), 44 | map: sourcemap ? s.generateMap() : null 45 | } 46 | } 47 | } 48 | 49 | function parseFind(find) { 50 | if (find instanceof RegExp) 51 | return new RegExp(find, find.flags + (find.flags.includes('g') ? '' : 'g')) 52 | 53 | const regex = find.match(/^\/(.*)\/([yumgis]*)$/) 54 | return regex 55 | ? new RegExp(regex[1], regex[2] + (regex[2].includes('g') ? '' : 'g')) 56 | : new RegExp(escapeRegExp(find), 'g') 57 | } 58 | } 59 | 60 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rollup-plugin-modify", 3 | "version": "2.0.1", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "balanced-match": { 8 | "version": "1.0.0", 9 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 10 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" 11 | }, 12 | "brace-expansion": { 13 | "version": "1.1.11", 14 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 15 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 16 | "requires": { 17 | "balanced-match": "^1.0.0", 18 | "concat-map": "0.0.1" 19 | } 20 | }, 21 | "concat-map": { 22 | "version": "0.0.1", 23 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 24 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 25 | }, 26 | "fs.realpath": { 27 | "version": "1.0.0", 28 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 29 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" 30 | }, 31 | "glob": { 32 | "version": "7.1.3", 33 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", 34 | "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", 35 | "requires": { 36 | "fs.realpath": "^1.0.0", 37 | "inflight": "^1.0.4", 38 | "inherits": "2", 39 | "minimatch": "^3.0.4", 40 | "once": "^1.3.0", 41 | "path-is-absolute": "^1.0.0" 42 | } 43 | }, 44 | "inflight": { 45 | "version": "1.0.6", 46 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 47 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 48 | "requires": { 49 | "once": "^1.3.0", 50 | "wrappy": "1" 51 | } 52 | }, 53 | "inherits": { 54 | "version": "2.0.3", 55 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 56 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 57 | }, 58 | "magic-string": { 59 | "version": "0.25.1", 60 | "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.1.tgz", 61 | "integrity": "sha512-sCuTz6pYom8Rlt4ISPFn6wuFodbKMIHUMv4Qko9P17dpxb7s52KJTmRuZZqHdGmLCK9AOcDare039nRIcfdkEg==", 62 | "requires": { 63 | "sourcemap-codec": "^1.4.1" 64 | } 65 | }, 66 | "minimatch": { 67 | "version": "3.0.4", 68 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 69 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 70 | "requires": { 71 | "brace-expansion": "^1.1.7" 72 | } 73 | }, 74 | "once": { 75 | "version": "1.4.0", 76 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 77 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 78 | "requires": { 79 | "wrappy": "1" 80 | } 81 | }, 82 | "ospec": { 83 | "version": "3.1.0", 84 | "resolved": "https://registry.npmjs.org/ospec/-/ospec-3.1.0.tgz", 85 | "integrity": "sha512-+nGtjV3vlADp+UGfL51miAh/hB4awPBkQrArhcgG4trAaoA2gKt5bf9w0m9ch9zOr555cHWaCHZEDiBOkNZSxw==", 86 | "requires": { 87 | "glob": "^7.1.3" 88 | } 89 | }, 90 | "path-is-absolute": { 91 | "version": "1.0.1", 92 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 93 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" 94 | }, 95 | "sourcemap-codec": { 96 | "version": "1.4.3", 97 | "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.3.tgz", 98 | "integrity": "sha512-vFrY/x/NdsD7Yc8mpTJXuao9S8lq08Z/kOITHz6b7YbfI9xL8Spe5EvSQUHOI7SbpY8bRPr0U3kKSsPuqEGSfA==" 99 | }, 100 | "wrappy": { 101 | "version": "1.0.2", 102 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 103 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rollup-plugin-modify", 3 | "version": "3.0.0", 4 | "description": "Modify rollup output with find / replace dynamically", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "ospec test" 8 | }, 9 | "keywords": [ 10 | "rollup-plugin", 11 | "replace", 12 | "find", 13 | "regex", 14 | "regexp", 15 | "modify", 16 | "codemod", 17 | "magic-string", 18 | "transform" 19 | ], 20 | "license": "WTFPL", 21 | "author": "Rasmus Porsager ", 22 | "repository": "porsager/rollup-plugin-modify", 23 | "dependencies": { 24 | "magic-string": "0.25.2", 25 | "ospec": "3.1.0" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | const o = require('ospec') 2 | , m = require('../index.js') 3 | 4 | o('find replace string', () => { 5 | const result = m({ 6 | find: 'this', 7 | replace: 'that' 8 | }).transform('replace this here') 9 | 10 | o(result.code).equals('replace that here') 11 | }) 12 | 13 | o('find replace regex', () => { 14 | const result = m({ 15 | find: /this/m, 16 | replace: 'that' 17 | }).transform('replace this here this there') 18 | 19 | o(result.code).equals('replace that here that there') 20 | }) 21 | 22 | o('find replace regex function', () => { 23 | const result = m({ 24 | find: /this/, 25 | replace: (m) => m.split('').reverse().join('') 26 | }).transform('replace this here this there') 27 | 28 | o(result.code).equals('replace siht here siht there') 29 | }) 30 | 31 | o('key, value', () => { 32 | const result = m({ 33 | wat: 'woot' 34 | }).transform('say wat?') 35 | 36 | o(result.code).equals('say woot?') 37 | }) 38 | 39 | o('multiple key, value sets', () => { 40 | const result = m({ 41 | wat: 'woot', 42 | say: 'think', 43 | 'process.env.PORT': 5000 44 | }).transform('say wat, process.env.PORT?') 45 | 46 | o(result.code).equals('think woot, 5000?') 47 | }) 48 | 49 | o('regex custom keys', () => { 50 | const result = m({ 51 | '/.a./': 'woot' 52 | }).transform('say wat?') 53 | 54 | o(result.code).equals('woot woot?') 55 | }) 56 | --------------------------------------------------------------------------------