├── .gitignore ├── .vscode └── settings.json ├── .npmignore ├── .babelrc ├── .circleci └── config.yml ├── package.json ├── README.md └── src ├── index.ts └── index.test.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "deepscan.enable": true 3 | } -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .lock 3 | .babelrc 4 | .test.* 5 | .gitignore -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [["@babel/preset-env", { 3 | "targets": { 4 | "node": true 5 | } 6 | }], "@babel/preset-typescript"], 7 | } -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | jobs: 3 | build: 4 | docker: 5 | - image: circleci/node:8 6 | steps: 7 | - checkout 8 | - run: 9 | name: Install dependencies 10 | command: yarn install 11 | - run: 12 | name: Run tests 13 | command: yarn test 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "corejs-upgrade-webpack-plugin", 3 | "version": "4.0.0", 4 | "description": "⛔️ DEPRECATED - A webpack plugin that transforms core-js v2 paths to core-js v3 paths", 5 | "keywords": [ 6 | "core-js", 7 | "path", 8 | "resolve", 9 | "transform", 10 | "webpack" 11 | ], 12 | "homepage": "https://github.com/ndelangen/corejs-upgrade-webpack-plugin", 13 | "bugs": { 14 | "url": "https://github.com/ndelangen/corejs-upgrade-webpack-plugin/issues" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "https://github.com/ndelangen/corejs-upgrade-webpack-plugin.git" 19 | }, 20 | "license": "MIT", 21 | "author": "Norbert de Langen ", 22 | "main": "dist/index.js", 23 | "scripts": { 24 | "build": "babel src -d dist --extensions '.ts'", 25 | "generate-types": "tsc --emitDeclarationOnly --declaration src/index.ts --esModuleInterop --outDir dist", 26 | "prepublish": "npm run build && npm run generate-types", 27 | "test": "jest" 28 | }, 29 | "dependencies": { 30 | "babel-runtime": "^6.26.0", 31 | "core-js": "^3.6.4", 32 | "resolve-from": "^5.0.0", 33 | "webpack": "^4.42.1" 34 | }, 35 | "devDependencies": { 36 | "@babel/cli": "^7.8.4", 37 | "@babel/core": "^7.9.0", 38 | "@babel/preset-env": "^7.9.0", 39 | "@babel/preset-typescript": "^7.9.0", 40 | "@types/webpack": "^4.41.8", 41 | "eslint": "^6.8.0", 42 | "jest": "^25.2.3", 43 | "typescript": "^3.8.3" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ⛔️ DEPRECATED 2 | 3 | ***This module is deprecated. It is adviced not to use this module!*** 4 | 5 | Using this module could easily result in difficult to debug errors. 6 | 7 |
8 |
9 |
10 |
11 |
12 |
13 | 14 | __Original description:__ 15 | 16 | # CoreJS Upgrade Webpack Plugin 17 | 18 | I wrote this to ensure the latest version of core-js is used everywhere in an application. 19 | 20 | Sometimes you're depending on components or libraries that haven't updated yet, and this can increase bundle-size, or even break your app if these dependencies didn't have core-js as a dependency themselves. 21 | 22 | This Webpack Plugin will essentially do a search and replace on all requires and if the require path matches `/core-js/` it will try and resolve the require. 23 | If it can, nothing happens. If the resolve fails (this would normally break your app) this plugin tries to map the old core-js path to the new path structure, and resolve that instead. 24 | 25 | This plugin will allow you to specify a `resolveFrom` option, so you can resolve core-js from any path you'd like. 26 | This is useful if you know there are going to be multiple core-js version installed, and you want to pick a specific one installed somewhere. 27 | 28 | ## Install 29 | 30 | ```sh 31 | yarn add corejs-upgrade-webpack-plugin 32 | ``` 33 | 34 | ## Usage 35 | 36 | simple example: 37 | 38 | ```js 39 | import CoreJSUpgradeWebpackPlugin from 'corejs-upgrade-webpack-plugin'; 40 | 41 | // add this to your webpack.plugins config 42 | new CoreJSUpgradeWebpackPlugin(); 43 | ``` 44 | 45 | example with options: 46 | 47 | ```js 48 | import CoreJSUpgradeWebpackPlugin from 'corejs-upgrade-webpack-plugin'; 49 | 50 | // add this to your webpack.plugins config 51 | new CoreJSUpgradeWebpackPlugin({ 52 | resolveFrom: [process.cwd()], 53 | }); 54 | ``` 55 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { NormalModuleReplacementPlugin } from 'webpack'; 2 | import resolveFrom from 'resolve-from'; 3 | 4 | const rewriteAndPreservePrefix = (originalRequest: string, newPath: string, newModuleName = 'core-js') => { 5 | const result = originalRequest.match(/(.*\/)core-js\/.*/); 6 | const requestPrefix = result ? result[1] : ''; 7 | 8 | return `${requestPrefix}${newModuleName}/${newPath}`; 9 | }; 10 | 11 | const rewriteRenamedModules = (path: string) => { 12 | if (path === 'web.dom.iterable') { 13 | return path.replace('web.dom.', 'web.dom-collections.') 14 | } 15 | 16 | return path; 17 | } 18 | 19 | export const rewriteCoreJsRequest = (originalRequest: string, lowerVersion = false) => { 20 | if (!originalRequest) { 21 | throw new Error('no originalRequest') 22 | } 23 | if (/core-js\/modules\/es(6|7)\.(.*)/.test(originalRequest)) { 24 | const [,matchedVersion, matchedPath] = originalRequest.match(/core-js\/modules\/es(6|7)\.(.*)/); 25 | 26 | const version = matchedVersion; 27 | const path = rewriteRenamedModules(matchedPath); 28 | 29 | if (version === '6' || lowerVersion) { 30 | return rewriteAndPreservePrefix(originalRequest, `modules/es.${path}`); 31 | } 32 | if (version === '7') { 33 | return rewriteAndPreservePrefix(originalRequest, `modules/esnext.${path}`); 34 | } 35 | } 36 | 37 | if (/core-js(?:\/library)?\/fn\/(.*)/.test(originalRequest)) { 38 | const [,matchedPath] = originalRequest.match(/core-js(?:\/library)?\/fn\/(.*)/); 39 | 40 | const path = rewriteRenamedModules(matchedPath); 41 | 42 | return rewriteAndPreservePrefix(originalRequest, `features/${path}`, 'core-js-pure'); 43 | } 44 | 45 | if (/core-js\/es(5|6|7)(.*)/.test(originalRequest)) { 46 | const [,matchedVersion, matchedPath] = originalRequest.match(/core-js\/es(5|6|7)(.*)?/); 47 | 48 | const version = matchedVersion; 49 | 50 | if (version === '5') { 51 | return null; 52 | } 53 | if (version === '6' || lowerVersion) { 54 | const asAModule = matchedPath.replace('.js', ''); 55 | const path = rewriteRenamedModules(asAModule); 56 | 57 | return rewriteAndPreservePrefix(originalRequest, `es${path}`); 58 | } 59 | if (version === '7') { 60 | return null; 61 | } 62 | } 63 | 64 | if (/core-js\/(object)\/(.*)/.test(originalRequest)) { 65 | const [,matchedPath] = originalRequest.match(/core-js\/(.*)?/); 66 | 67 | const path = rewriteRenamedModules(matchedPath); 68 | 69 | return rewriteAndPreservePrefix(originalRequest, `features/${path}`); 70 | } 71 | 72 | return originalRequest; 73 | }; 74 | 75 | export interface Options { 76 | resolveFrom: string | false | string[]; 77 | } 78 | 79 | const defaultOptions = { 80 | resolveFrom: false, 81 | resolveBackup: false, 82 | } as Options 83 | 84 | export default function CoreJSUpgradeWebpackPlugin(options: Options) { 85 | options = Object.assign({}, defaultOptions, options || {}); 86 | 87 | const resolvers = options.resolveFrom ? [].concat(options.resolveFrom).map(r => resolveFrom.bind(null, r)) : []; 88 | 89 | return new NormalModuleReplacementPlugin(/core-js/, resource => { 90 | const originalRequest = (resource.userRequest || resource.request) as string; 91 | if (originalRequest.startsWith('./') || originalRequest.startsWith('../')) { 92 | return; 93 | } 94 | if (originalRequest.match(/@babel\/runtime\/core-js/)) { 95 | return; 96 | } 97 | 98 | try { 99 | require.resolve(originalRequest, { paths: [resource.context] }); 100 | } catch (originalError) { 101 | let error = true; 102 | 103 | for (const resolve of resolvers) { 104 | // attempt the core-js v2 from backup 105 | if (error) { 106 | try { 107 | // eslint-disable-next-line no-param-reassign 108 | resource.request = resolve(originalRequest); 109 | error = false; 110 | } catch (e) {} 111 | } 112 | 113 | // attempt to upgrade the path from core-js v2 to v3 from backup 114 | if (error) { 115 | try { 116 | // eslint-disable-next-line no-param-reassign 117 | resource.request = resolve(rewriteCoreJsRequest(originalRequest)); 118 | error = false; 119 | } catch (e) {} 120 | } 121 | 122 | // attempt to downgrade the path from es7 to es6 from backup 123 | if (error) { 124 | try { 125 | // eslint-disable-next-line no-param-reassign 126 | resource.request = resolve(rewriteCoreJsRequest(originalRequest, true)); 127 | error = false; 128 | } catch (e) {} 129 | } 130 | } 131 | 132 | if (error) { 133 | throw originalError; 134 | } 135 | } 136 | }); 137 | }; 138 | -------------------------------------------------------------------------------- /src/index.test.js: -------------------------------------------------------------------------------- 1 | import CoreJsAutoUpgradePlugin, { rewriteCoreJsRequest } from './index'; 2 | 3 | describe('CoreJsAutoUpgradePlugin', () => { 4 | it('should be constructable, without options', () => { 5 | expect(() => new CoreJsAutoUpgradePlugin()).not.toThrow() 6 | }); 7 | it('should be constructable, with options', () => { 8 | expect(() => new CoreJsAutoUpgradePlugin({ 9 | resolveFrom: __dirname, 10 | })).not.toThrow() 11 | }); 12 | }); 13 | 14 | describe('rewriteCoreJsRequest', () => { 15 | const fakeRequire = jest.mock(); 16 | 17 | describe('rewrite `core-js/modules/*`', () => { 18 | it('should rewrite `core-js/modules/es6.*` import to `core-js/modules/es.*`', () => { 19 | expect(rewriteCoreJsRequest('core-js/modules/es6.object.is-frozen.js')).toBe( 20 | 'core-js/modules/es.object.is-frozen.js' 21 | ); 22 | }); 23 | 24 | it('should rewrite `core-js/modules/es7.*` import to `core-js/modules/esnext.*`', () => { 25 | expect(rewriteCoreJsRequest('core-js/modules/es7.math.iaddh.js')).toBe( 26 | 'core-js/modules/esnext.math.iaddh.js' 27 | ); 28 | }); 29 | 30 | it('should rewrite `core-js/modules/es.*` import to `core-js/modules/es.*`', () => { 31 | expect(rewriteCoreJsRequest('core-js/modules/es.object.is-frozen.js')).toBe( 32 | 'core-js/modules/es.object.is-frozen.js' 33 | ); 34 | }); 35 | 36 | it('should rewrite `core-js/modules/esnext.*` import to `core-js/modules/esnext.*`', () => { 37 | expect(rewriteCoreJsRequest('core-js/modules/esnext.set.some.js')).toBe( 38 | 'core-js/modules/esnext.set.some.js' 39 | ); 40 | }); 41 | }); 42 | 43 | describe('rewrite `core-js/library/fn/*` and `core-js/fn/*`', () => { 44 | it('should rewrite `core-js/library/*` import to `core-js-pure/features/*`', () => { 45 | expect(rewriteCoreJsRequest('core-js/library/fn/object/assign')).toBe( 46 | 'core-js-pure/features/object/assign' 47 | ); 48 | }); 49 | 50 | it('should rewrite `core-js/fn/*` import to `core-js-pure/features/*`', () => { 51 | expect(rewriteCoreJsRequest('core-js/fn/object/assign')).toBe( 52 | 'core-js-pure/features/object/assign' 53 | ); 54 | }); 55 | }); 56 | 57 | describe('rewrite `core-js/es(5|6|7)/*`', () => { 58 | it('should not rewrite `core-js/es5` import', () => { 59 | expect(rewriteCoreJsRequest('core-js/es5')).toBeNull(); 60 | }); 61 | 62 | it('should rewrite `core-js/es6/*` import to `core-js/es/*`', () => { 63 | expect(rewriteCoreJsRequest('core-js/es6/object.js')).toBe('core-js/es/object'); 64 | 65 | expect(rewriteCoreJsRequest('core-js/es6/parse-int')).toBe('core-js/es/parse-int'); 66 | }); 67 | 68 | it('should not rewrite `core-js/es7` import`', () => { 69 | expect(rewriteCoreJsRequest('core-js/es7/array.js')).toBeNull(); 70 | }); 71 | }); 72 | 73 | describe('rewrite `core-js/object/*`', () => { 74 | it('should rewrite `core-js/object/*` import to `core-js/features/*`', () => { 75 | expect(rewriteCoreJsRequest('core-js/object/assign.js')).toBe( 76 | 'core-js/features/object/assign.js' 77 | ); 78 | 79 | expect(rewriteCoreJsRequest('../core-js/object/assign')).toBe( 80 | '../core-js/features/object/assign' 81 | ); 82 | }); 83 | }); 84 | 85 | it('should preserve request prefix when upgrading the request', () => { 86 | expect(rewriteCoreJsRequest('../foo/core-js/modules/es6.bar.js')).toBe( 87 | '../foo/core-js/modules/es.bar.js' 88 | ); 89 | }); 90 | }); 91 | 92 | describe('rewriteCoreJsRequest with downgrade option enabled', () => { 93 | const fakeRequire = jest.mock(); 94 | 95 | describe('rewrite `core-js/modules/*`', () => { 96 | it('should rewrite `core-js/modules/es6.*` import to `core-js/modules/es.*`', () => { 97 | expect(rewriteCoreJsRequest('core-js/modules/es6.object.is-frozen.js', true)).toBe( 98 | 'core-js/modules/es.object.is-frozen.js' 99 | ); 100 | }); 101 | 102 | it('should rewrite `core-js/modules/es7.*` import to `core-js/modules/es.*`', () => { 103 | expect(rewriteCoreJsRequest('core-js/modules/es7.symbol.async-iterator', true)).toBe( 104 | 'core-js/modules/es.symbol.async-iterator' 105 | ); 106 | }); 107 | 108 | it('should rewrite `core-js/modules/es.*` import to `core-js/modules/es.*`', () => { 109 | expect(rewriteCoreJsRequest('core-js/modules/es.object.is-frozen.js', true)).toBe( 110 | 'core-js/modules/es.object.is-frozen.js' 111 | ); 112 | }); 113 | 114 | it('should rewrite `core-js/modules/esnext.*` import to `core-js/modules/esnext.*`', () => { 115 | expect(rewriteCoreJsRequest('core-js/modules/esnext.set.some.js', true)).toBe( 116 | 'core-js/modules/esnext.set.some.js' 117 | ); 118 | }); 119 | }); 120 | }); 121 | --------------------------------------------------------------------------------