Skip to content

Commit

Permalink
feat(build): use __DEV__ to control development mode (pmndrs#789)
Browse files Browse the repository at this point in the history
* feat(build): use __DEV__ to control development mode

* fix workflow

* missing env in systemjs build
  • Loading branch information
dai-shi authored Feb 9, 2022
1 parent e90e8bc commit 5b938fb
Show file tree
Hide file tree
Showing 8 changed files with 241 additions and 33 deletions.
57 changes: 57 additions & 0 deletions .github/workflows/test-multiple-builds.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: Test Multiple Builds

on:
push:
branches: [main]
pull_request:
types: [opened, synchronize]

jobs:
test_matrix:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
build: [cjs, umd] # [cjs, esm, umd, system]
env: [development, production]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '12'
cache: yarn
- run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
- run: yarn install --frozen-lockfile --check-files
- run: yarn build
- name: Patch for DEV-ONLY
if: ${{ matrix.env == 'development' }}
run: |
sed -i~ "s/it[a-zA-Z]*('\[PRD-ONLY\]/it.skip('/" tests/*.tsx
- name: Patch for PRD-ONLY
if: ${{ matrix.env == 'production' }}
run: |
sed -i~ "s/it[a-zA-Z]*('\[DEV-ONLY\]/it.skip('/" tests/*.tsx
- name: Patch for CJS
if: ${{ matrix.build == 'cjs' }}
run: |
sed -i~ "s/<rootDir>\/src\(.*\)\.ts/<rootDir>\/dist\1.js/" package.json
- name: Patch for ESM
if: ${{ matrix.build == 'esm' }}
run: |
sed -i~ "s/<rootDir>\/src\(.*\)\.ts/<rootDir>\/dist\/esm\1.js" package.json
sed -i~ "1s/^/import.meta.env=import.meta.env||{};import.meta.env.MODE='${NODE_ENV}';/" tests/*.tsx
env:
NODE_ENV: ${{ matrix.env }}
- name: Patch for UMD/SystemJS
if: ${{ matrix.build == 'umd' || matrix.build == 'system' }}
run: |
sed -i~ "s/<rootDir>\/src\(.*\)\.ts/<rootDir>\/dist\/${BUILD}\1.${NODE_ENV}.js/" package.json
env:
BUILD: ${{ matrix.build }}
NODE_ENV: ${{ matrix.env }}
- name: Test ${{ matrix.build }} ${{ matrix.env }}
run: |
cat package.json
yarn test:ci
env:
NODE_ENV: ${{ matrix.env }}
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"sideEffects": false,
"scripts": {
"prebuild": "shx rm -rf dist",
"build": "concurrently 'yarn:build:*'",
"build": "concurrently -m 8 'yarn:build:*'",
"build:base": "rollup -c",
"build:vanilla": "rollup -c --config-vanilla",
"build:middleware": "rollup -c --config-middleware",
Expand Down Expand Up @@ -106,6 +106,9 @@
"@swc/jest"
]
},
"globals": {
"__DEV__": true
},
"moduleNameMapper": {
"^zustand$": "<rootDir>/src/index.ts",
"^zustand/(.*)$": "<rootDir>/src/$1.ts"
Expand Down Expand Up @@ -136,6 +139,7 @@
"@babel/preset-env": "^7.16.5",
"@rollup/plugin-babel": "^5.3.0",
"@rollup/plugin-node-resolve": "^13.1.1",
"@rollup/plugin-replace": "^3.0.1",
"@rollup/plugin-typescript": "^8.3.0",
"@swc/core": "^1.2.122",
"@swc/jest": "^0.2.15",
Expand Down Expand Up @@ -165,6 +169,7 @@
"react-dom": "^17.0.2",
"rollup": "^2.62.0",
"rollup-plugin-esbuild": "^4.7.2",
"rollup-plugin-terser": "^7.0.2",
"shx": "^0.3.3",
"typescript": "^4.5.4"
},
Expand Down
72 changes: 51 additions & 21 deletions rollup.config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import path from 'path'
import babelPlugin from '@rollup/plugin-babel'
import resolve from '@rollup/plugin-node-resolve'
import replace from '@rollup/plugin-replace'
import typescript from '@rollup/plugin-typescript'
import esbuild from 'rollup-plugin-esbuild'
import { terser } from 'rollup-plugin-terser'
const createBabelConfig = require('./babel.config')

const extensions = ['.js', '.ts', '.tsx']
Expand All @@ -21,9 +23,9 @@ function getBabelOptions(targets) {
}
}

function getEsbuild(target) {
function getEsbuild(target, env = 'development') {
return esbuild({
minify: false,
minify: env === 'production',
target,
tsconfig: path.resolve('./tsconfig.json'),
})
Expand Down Expand Up @@ -54,68 +56,96 @@ function createESMConfig(input, output) {
{ file: `${output}.mjs`, format: 'esm' },
],
external,
plugins: [resolve({ extensions }), getEsbuild('node12')],
plugins: [
resolve({ extensions }),
replace({
__DEV__: '(import.meta.env&&import.meta.env.MODE)!=="production"',
preventAssignment: true,
}),
getEsbuild('node12'),
],
}
}

function createCommonJSConfig(input, output) {
return {
input,
output: { file: output, format: 'cjs', exports: 'named' },
output: { file: `${output}.js`, format: 'cjs', exports: 'named' },
external,
plugins: [
resolve({ extensions }),
replace({
__DEV__: 'process.env.NODE_ENV!=="production"',
preventAssignment: true,
}),
babelPlugin(getBabelOptions({ ie: 11 })),
],
}
}

function createUMDConfig(input, output) {
function createUMDConfig(input, output, env) {
const c = output.split('/').pop()
return {
input,
output: {
file: output,
file: `${output}.${env}.js`,
format: 'umd',
exports: 'named',
name: 'zustand',
name:
c === 'index'
? 'zustand'
: `zustand${c.slice(0, 1).toUpperCase()}${c.slice(1)}`,
globals: {
react: 'React',
},
},
external,
plugins: [
resolve({ extensions }),
replace({
__DEV__: env !== 'production' ? 'true' : 'false',
preventAssignment: true,
}),
babelPlugin(getBabelOptions({ ie: 11 })),
...(env === 'production' ? [terser()] : []),
],
}
}

function createSystemConfig(input, output) {
function createSystemConfig(input, output, env) {
return {
input,
output: {
file: output,
file: `${output}.${env}.js`,
format: 'system',
exports: 'named',
},
external,
plugins: [resolve({ extensions }), getEsbuild('node12')],
plugins: [
resolve({ extensions }),
replace({
__DEV__: env !== 'production' ? 'true' : 'false',
preventAssignment: true,
}),
getEsbuild('node12', env),
],
}
}

export default function (args) {
let c = Object.keys(args).find((key) => key.startsWith('config-'))
if (c) {
c = c.slice('config-'.length).replace(/_/g, '/')
return [
createCommonJSConfig(`src/${c}.ts`, `dist/${c}.js`),
createESMConfig(`src/${c}.ts`, `dist/esm/${c}`),
createUMDConfig(`src/${c}.ts`, `dist/umd/${c}.js`),
createSystemConfig(`src/${c}.ts`, `dist/system/${c}.js`),
]
} else {
c = 'index'
}
return [
createDeclarationConfig('src/index.ts', 'dist'),
createCommonJSConfig('src/index.ts', 'dist/index.js'),
createESMConfig('src/index.ts', 'dist/esm/index'),
createUMDConfig('src/index.ts', 'dist/umd/index.js'),
createSystemConfig('src/index.ts', 'dist/system/index.js'),
...(c === 'index' ? [createDeclarationConfig(`src/${c}.ts`, 'dist')] : []),
createCommonJSConfig(`src/${c}.ts`, `dist/${c}`),
createESMConfig(`src/${c}.ts`, `dist/esm/${c}`),
createUMDConfig(`src/${c}.ts`, `dist/umd/${c}`, 'development'),
createUMDConfig(`src/${c}.ts`, `dist/umd/${c}`, 'production'),
createSystemConfig(`src/${c}.ts`, `dist/system/${c}`, 'development'),
createSystemConfig(`src/${c}.ts`, `dist/system/${c}`, 'production'),
]
}
5 changes: 1 addition & 4 deletions src/middleware/devtools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,10 +176,7 @@ export function devtools<
}

if (!extensionConnector) {
if (
process.env.NODE_ENV === 'development' &&
typeof window !== 'undefined'
) {
if (__DEV__ && typeof window !== 'undefined') {
console.warn(
'[zustand devtools middleware] Please install/enable Redux devtools extension'
)
Expand Down
2 changes: 2 additions & 0 deletions src/types.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// eslint-disable-next-line no-var
declare var __DEV__: boolean
13 changes: 8 additions & 5 deletions tests/devtools.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,25 @@ it('connects to the extension by passing the options and initializes', () => {
})

describe('If there is no extension installed...', () => {
let savedDEV: boolean
beforeAll(() => {
savedDEV = __DEV__
;(window as any).__REDUX_DEVTOOLS_EXTENSION__ = undefined
})
afterAll(() => {
__DEV__ = savedDEV
;(window as any).__REDUX_DEVTOOLS_EXTENSION__ = extensionConnector
})

it('does not throw', () => {
__DEV__ = false
expect(() => {
create(devtools(() => ({ count: 0 })))
}).not.toThrow()
})

it('warns in dev env', () => {
const originalNodeEnv = process.env.NODE_ENV
process.env.NODE_ENV = 'development'
it('[DEV-ONLY] warns in dev env', () => {
__DEV__ = true
const originalConsoleWarn = console.warn
console.warn = jest.fn()

Expand All @@ -59,11 +62,11 @@ describe('If there is no extension installed...', () => {
'[zustand devtools middleware] Please install/enable Redux devtools extension'
)

process.env.NODE_ENV = originalNodeEnv
console.warn = originalConsoleWarn
})

it('does not warn if not in dev env', () => {
it('[PRD-ONLY] does not warn if not in dev env', () => {
__DEV__ = false
const consoleWarn = jest.spyOn(console, 'warn')

create(devtools(() => ({ count: 0 })))
Expand Down
Loading

0 comments on commit 5b938fb

Please sign in to comment.