diff --git a/lib/webpack-config/__snapshots__/create-webpack-config.test.js.snap b/lib/webpack-config/__snapshots__/create-webpack-config.test.js.snap index 6bd9de3..4613aed 100644 --- a/lib/webpack-config/__snapshots__/create-webpack-config.test.js.snap +++ b/lib/webpack-config/__snapshots__/create-webpack-config.test.js.snap @@ -29,7 +29,7 @@ Object { }, Object { "exclude": Array [ - /\\[\\\\/\\\\\\\\\\\\\\\\\\]node_modules\\[\\\\/\\\\\\\\\\\\\\\\\\]/, + /\\[/\\\\\\\\\\\\\\\\\\]node_modules\\[/\\\\\\\\\\\\\\\\\\]/, ], "loader": "/node_modules/babel-loader/lib/index.js", "options": Object { @@ -46,7 +46,9 @@ Object { "test": /\\\\\\.jsx\\?\\$/, }, Object { - "exclude": /@babel\\(\\?:\\\\/\\|\\\\\\\\\\{1,2\\}\\)runtime/, + "exclude": Array [ + /@babel\\(\\?:\\\\/\\|\\\\\\\\\\{1,2\\}\\)runtime/, + ], "loader": "/node_modules/babel-loader/lib/index.js", "options": Object { "babelrc": false, diff --git a/lib/webpack-config/babel-loader-config.js b/lib/webpack-config/babel-loader-config.js index 06d502f..4e86a1a 100644 --- a/lib/webpack-config/babel-loader-config.js +++ b/lib/webpack-config/babel-loader-config.js @@ -4,6 +4,7 @@ const fs = require('fs'); const path = require('path'); const browserslist = require('browserslist'); const chalk = require('chalk'); +const semver = require('semver'); const logger = require('../logger'); @@ -77,8 +78,7 @@ function getConfigForNodeModules(urc) { const loaderConfig = { test: /\.js$/, - // We want to avoid sending babel/runtime back to babel. - exclude: /@babel(?:\/|\\{1,2})runtime/, + exclude: getNodeModuleExclude({ urc }), loader: require.resolve('babel-loader'), options: { presets: [ @@ -116,6 +116,30 @@ function getConfigForNodeModules(urc) { return loaderConfig; } +// getNodeModuleExclude does two things: +// 1. Avoid sending babel/runtime back to babel. +// 2. If the app uses mapbox-gl 2.0+, do not transpile. mapbox-gl 2.0+ is +// incompatible with babel without additional configuration beacuse it uses +// an inlined webworker. +function getNodeModuleExclude({ urc }) { + const excludes = [/@babel(?:\/|\\{1,2})runtime/]; + + let usesMapboxGl2 = false; + try { + const pkg = JSON.parse( + fs.readFileSync(path.join(urc.rootDirectory, 'package.json'), 'utf8') + ); + const glJsVer = pkg.dependencies['mapbox-gl']; + usesMapboxGl2 = semver.gte(semver.coerce(glJsVer), '2.0.0'); + } catch (e) {} // eslint-disable-line + + if (usesMapboxGl2) { + excludes.push(/[/\\\\]node_modules\/mapbox-gl\/dist.*\.js/); + } + + return excludes; +} + // `babel-preset-mapbox` depends on the `browserslist` and // any change in its value would fail to change the default `cacheIdentifier` of `babel-loader` // hence leading to stale babel output. To mitigate this we need to create a more accurate `cacheIdentifier` diff --git a/lib/webpack-config/create-webpack-config.test.js b/lib/webpack-config/create-webpack-config.test.js index be832af..9a7e9b4 100644 --- a/lib/webpack-config/create-webpack-config.test.js +++ b/lib/webpack-config/create-webpack-config.test.js @@ -46,6 +46,73 @@ test('Basic Test', () => { ).resolves.toMatchSnapshot(); }); +test('Adds mapbox-gl to exclude if user is on 2.0.0 or above', () => { + getUserConfig.mockResolvedValueOnce({}); + const tempDir = tempy.directory(); + fs.writeFileSync( + path.join(tempDir, 'package.json'), + `{ + "name": "fake", + "version": "0.0.0", + "dependencies": { + "mapbox-gl": "^2.0.0" + } + }` + ); + + fs.writeFileSync( + path.join(tempDir, 'babel.config.js'), + `module.exports = {}` + ); + + const urcPromise = config( + getCliOpts({ + configPath: path.join(tempDir, 'underreact.config.js') + }) + ); + + return urcPromise.then(urc => { + const config = createWebpackConfig(urc); + expect(config.module.rules[0].oneOf[1].exclude).toEqual([ + /@babel(?:\/|\\{1,2})runtime/, + /[/\\\\]node_modules\/mapbox-gl\// + ]); + }); +}); + +test('Does not add mapbox-gl to exclude if user is on a version below 2.0.0', () => { + getUserConfig.mockResolvedValueOnce({}); + const tempDir = tempy.directory(); + fs.writeFileSync( + path.join(tempDir, 'package.json'), + `{ + "name": "fake", + "version": "0.0.0", + "dependencies": { + "mapbox-gl": "~1.9.0" + } + }` + ); + + fs.writeFileSync( + path.join(tempDir, 'babel.config.js'), + `module.exports = {}` + ); + + const urcPromise = config( + getCliOpts({ + configPath: path.join(tempDir, 'underreact.config.js') + }) + ); + + return urcPromise.then(urc => { + const config = createWebpackConfig(urc); + expect(config.module.rules[0].oneOf[1].exclude).toEqual([ + /@babel(?:\/|\\{1,2})runtime/ + ]); + }); +}); + test('Uses babel.config.js if it exists at project root', () => { getUserConfig.mockResolvedValueOnce({}); const tempDir = tempy.directory(); diff --git a/package-lock.json b/package-lock.json index 535227e..afe896d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@mapbox/underreact", - "version": "0.5.4", + "version": "0.6.0-dev.3", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -68,6 +68,11 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" } } }, @@ -1399,6 +1404,11 @@ } } }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -3460,6 +3470,11 @@ "caniuse-lite": "^1.0.30000844", "electron-to-chromium": "^1.3.47" } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" } } }, @@ -3907,13 +3922,27 @@ } }, "browserslist": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.0.2.tgz", - "integrity": "sha512-lpujC4zv1trcKUUwfD4pFVNga4YSpB3sLB+/I+A8gvGQxno1c0dMB2aCQy0FE5oUNIDjD9puFiFF0zeS6Ji48w==", + "version": "4.16.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.0.tgz", + "integrity": "sha512-/j6k8R0p3nxOC6kx5JGAxsnhc9ixaWJfYc+TNTzxg6+ARaESAvQGV7h0uNOB4t+pLQJZWzcrMxXOxjgsCj3dqQ==", "requires": { - "caniuse-lite": "^1.0.30000876", - "electron-to-chromium": "^1.3.57", - "node-releases": "^1.0.0-alpha.11" + "caniuse-lite": "^1.0.30001165", + "colorette": "^1.2.1", + "electron-to-chromium": "^1.3.621", + "escalade": "^3.1.1", + "node-releases": "^1.1.67" + }, + "dependencies": { + "caniuse-lite": { + "version": "1.0.30001170", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001170.tgz", + "integrity": "sha512-Dd4d/+0tsK0UNLrZs3CvNukqalnVTRrxb5mcQm8rHL49t7V5ZaTygwXkrq+FB+dVDf++4ri8eJnFEJAB8332PA==" + }, + "electron-to-chromium": { + "version": "1.3.633", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.633.tgz", + "integrity": "sha512-bsVCsONiVX1abkWdH7KtpuDAhsQ3N3bjPYhROSAXE78roJKet0Y5wznA14JE9pzbwSZmSMAW6KiKYf1RvbTJkA==" + } } }, "bser": { @@ -4382,6 +4411,11 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz", "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=" }, + "colorette": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz", + "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==" + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -4661,6 +4695,13 @@ "semver": "^5.5.0", "shebang-command": "^1.2.0", "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } } }, "crypto-browserify": { @@ -5336,6 +5377,11 @@ "is-symbol": "^1.0.1" } }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -5520,6 +5566,12 @@ "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true } } }, @@ -10964,15 +11016,20 @@ "semver": "^5.5.0", "shellwords": "^0.1.1", "which": "^1.3.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } } }, "node-releases": { - "version": "1.0.0-alpha.11", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.0.0-alpha.11.tgz", - "integrity": "sha512-CaViu+2FqTNYOYNihXa5uPS/zry92I3vPU4nCB6JB3OeZ2UGtOpF5gRwuN4+m3hbEcL47bOXyun1jX2iC+3uEQ==", - "requires": { - "semver": "^5.3.0" - } + "version": "1.1.67", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.67.tgz", + "integrity": "sha512-V5QF9noGFl3EymEwUYzO+3NTDpGfQB4ve6Qfnzf3UNydMhjQRVPR1DZTuvWiLzaFJYw2fmDwAfnRNEVb64hSIg==" }, "normalize-package-data": { "version": "2.4.0", @@ -10983,6 +11040,13 @@ "is-builtin-module": "^1.0.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } } }, "normalize-path": { @@ -12944,9 +13008,27 @@ } }, "semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha1-3Eu8emyp2Rbe5dQ1FvAJK1j3uKs=" + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "requires": { + "lru-cache": "^6.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } }, "semver-compare": { "version": "1.0.0", diff --git a/package.json b/package.json index c3ff01c..0ca1bf3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mapbox/underreact", - "version": "0.5.4", + "version": "0.6.0-dev.3", "description": "Minimal, extensible React app build system that you won't need to eject", "main": "index.js", "scripts": { @@ -37,7 +37,7 @@ "assets-webpack-plugin": "^3.8.4", "autoprefixer": "^8.6.5", "babel-loader": "^8.0.2", - "browserslist": "^4.0.2", + "browserslist": "^4.16.0", "chalk": "^2.4.1", "chokidar": "^2.0.4", "cpy": "^7.0.1", @@ -55,6 +55,7 @@ "promise": "^8.0.1", "remark-preset-davidtheclark": "^0.10.0", "resolve-pkg": "^1.0.0", + "semver": "^7.3.4", "serve-handler": "^5.0.5", "serve-static": "^1.13.2", "source-map-url": "^0.4.0",