Skip to content

Commit aff00c9

Browse files
authored
Merge pull request #4511 from reduxjs/feature/build-esm-fixes
2 parents 36d2aef + 19257f5 commit aff00c9

File tree

10 files changed

+736
-42
lines changed

10 files changed

+736
-42
lines changed

.codesandbox/ci.json

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
{
2-
"sandboxes": [
3-
"vanilla",
4-
"vanilla-ts"
5-
],
6-
"node": "14"
2+
"sandboxes": ["vanilla", "vanilla-ts"],
3+
"node": "16"
74
}

.github/workflows/test.yaml

+71
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,74 @@ jobs:
127127
yarn tsc --version
128128
yarn check-types
129129
yarn test:types
130+
131+
test-published-artifact:
132+
name: Test Published Artifact ${{ matrix.example }}
133+
134+
needs: [build]
135+
runs-on: ubuntu-latest
136+
strategy:
137+
fail-fast: false
138+
matrix:
139+
node: ['16.x']
140+
example:
141+
[
142+
'cra4',
143+
'cra5',
144+
'next',
145+
'vite',
146+
'node-standard',
147+
'node-esm',
148+
'are-the-types-wrong'
149+
]
150+
steps:
151+
- name: Checkout repo
152+
uses: actions/checkout@v2
153+
154+
- name: Use node ${{ matrix.node }}
155+
uses: actions/setup-node@v2
156+
with:
157+
node-version: ${{ matrix.node }}
158+
cache: 'yarn'
159+
160+
- name: Clone RTK repo
161+
run: git clone https://github.com/reduxjs/redux-toolkit.git ./redux-toolkit
162+
163+
- name: Check folder contents
164+
run: ls -l .
165+
166+
- name: Install deps
167+
working-directory: ./redux-toolkit/examples/publish-ci/${{ matrix.example }}
168+
run: yarn install
169+
170+
- uses: actions/download-artifact@v2
171+
with:
172+
name: package
173+
path: ./redux-toolkit/examples/publish-ci/${{ matrix.example }}
174+
175+
- name: Check folder contents
176+
working-directory: ./redux-toolkit/examples/publish-ci/${{ matrix.example }}
177+
run: ls -l .
178+
179+
- name: Install build artifact
180+
working-directory: ./redux-toolkit/examples/publish-ci/${{ matrix.example }}
181+
run: yarn add ./package.tgz
182+
183+
- name: Show installed package versions
184+
working-directory: ./redux-toolkit/examples/publish-ci/${{ matrix.example }}
185+
run: yarn info redux && yarn why redux
186+
187+
- name: Build example
188+
working-directory: ./redux-toolkit/examples/publish-ci/${{ matrix.example }}
189+
run: yarn build
190+
191+
- name: Run test step
192+
working-directory: ./redux-toolkit/examples/publish-ci/${{ matrix.example }}
193+
run: yarn test
194+
if: matrix.example != 'are-the-types-wrong'
195+
196+
- name: Run test step
197+
working-directory: ./redux-toolkit/examples/publish-ci/${{ matrix.example }}
198+
# Ignore "FalseCJS" errors in the `attw` job
199+
run: yarn test -n FalseCJS
200+
if: matrix.example == 'are-the-types-wrong'

package.json

+11-13
Original file line numberDiff line numberDiff line change
@@ -23,27 +23,23 @@
2323
"Dan Abramov <dan.abramov@me.com> (https://github.com/gaearon)",
2424
"Andrew Clark <acdlite@me.com> (https://github.com/acdlite)"
2525
],
26-
"type": "module",
27-
"module": "dist/es/index.js",
28-
"main": "dist/cjs/index.cjs",
29-
"types": "types/index.d.ts",
26+
"main": "dist/cjs/redux.cjs",
27+
"module": "dist/redux.mjs",
28+
"types": "dist/redux.d.ts",
3029
"exports": {
3130
"./package.json": "./package.json",
3231
".": {
33-
"types": "./types/index.d.ts",
34-
"import": "./dist/es/index.js",
35-
"default": "./dist/cjs/index.cjs"
32+
"types": "./dist/redux.d.ts",
33+
"import": "./dist/redux.mjs",
34+
"default": "./dist/cjs/redux.cjs"
3635
}
3736
},
3837
"files": [
3938
"dist",
40-
"lib",
41-
"es",
42-
"src",
43-
"types"
39+
"src"
4440
],
4541
"scripts": {
46-
"clean": "rimraf lib dist es coverage types",
42+
"clean": "rimraf dist",
4743
"format": "prettier --write \"{src,test}/**/*.{js,ts}\" \"**/*.md\"",
4844
"format:check": "prettier --list-different \"{src,test}/**/*.{js,ts}\" \"**/*.md\"",
4945
"lint": "eslint --ext js,ts src test",
@@ -52,7 +48,7 @@
5248
"test:types": "tsc -p test/typescript && echo \"Typetests passed\"",
5349
"test:watch": "vitest",
5450
"test:cov": "vitest --coverage",
55-
"build": "rollup -c",
51+
"build": "tsup",
5652
"prepublishOnly": "yarn clean && yarn check-types && yarn format:check && yarn lint && yarn test",
5753
"prepack": "yarn build",
5854
"examples:lint": "eslint --ext js,ts examples",
@@ -79,6 +75,7 @@
7975
"@typescript-eslint/eslint-plugin": "^5.36.2",
8076
"@typescript-eslint/parser": "^5.36.2",
8177
"cross-env": "^7.0.3",
78+
"esbuild-extra": "^0.1.3",
8279
"eslint": "^8.23.0",
8380
"eslint-config-react-app": "^7.0.1",
8481
"eslint-import-resolver-typescript": "^3.5.1",
@@ -94,6 +91,7 @@
9491
"rollup": "^3.12.0",
9592
"rollup-plugin-typescript2": "^0.34.1",
9693
"rxjs": "^7.5.6",
94+
"tsup": "^6.7.0",
9795
"typescript": "^4.8.3",
9896
"vitest": "^0.27.2"
9997
},

scripts/mangleErrors.cjs

+6-6
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,12 @@ module.exports = babel => {
103103
}
104104

105105
// Import the error message function
106-
const formatProdErrorMessageIdentifier =
107-
helperModuleImports.addDefault(
108-
path,
109-
'src/utils/formatProdErrorMessage',
110-
{ nameHint: 'formatProdErrorMessage' }
111-
)
106+
const formatProdErrorMessageIdentifier = helperModuleImports.addNamed(
107+
path,
108+
'formatProdErrorMessage',
109+
'src/utils/formatProdErrorMessage',
110+
{ nameHint: 'formatProdErrorMessage' }
111+
)
112112

113113
// Creates a function call to output the message to the error code page on the website
114114
const prodMessage = t.callExpression(

src/types/store.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Action, AnyAction } from './actions'
22
import { Reducer } from './reducers'
3-
import '../utils/symbol-observable'
3+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
4+
import _$$observable from '../utils/symbol-observable'
45

56
/**
67
* Internal "virtual" symbol used to make the `CombinedState` type unique.

src/utils/formatProdErrorMessage.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,9 @@
55
* during build.
66
* @param {number} code
77
*/
8-
function formatProdErrorMessage(code: number) {
8+
export function formatProdErrorMessage(code: number) {
99
return (
1010
`Minified Redux error #${code}; visit https://redux.js.org/Errors?code=${code} for the full message or ` +
1111
'use the non-minified dev environment for full errors. '
1212
)
1313
}
14-
15-
export default formatProdErrorMessage

test/utils/formatProdErrorMessage.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import formatProdErrorMessage from '@internal/utils/formatProdErrorMessage'
1+
import { formatProdErrorMessage } from '@internal/utils/formatProdErrorMessage'
22

33
describe('formatProdErrorMessage', () => {
44
it('returns message with expected code references', () => {

tsconfig.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"noUnusedLocals": true,
1616
"noUnusedParameters": true,
1717
"baseUrl": "./",
18-
"types": ["vitest/globals"],
18+
"types": ["vitest/globals", "esbuild-extra/global"],
1919
"paths": {
2020
"redux": ["src/index.ts"], // @remap-prod-remove-line
2121
"@internal/*": ["src/*"]

tsup.config.ts

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { defineConfig, Options } from 'tsup'
2+
3+
import * as babel from '@babel/core'
4+
import { Plugin } from 'esbuild'
5+
import { getBuildExtensions } from 'esbuild-extra'
6+
7+
// Extract error strings, replace them with error codes, and write messages to a file
8+
const mangleErrorsTransform: Plugin = {
9+
name: 'mangle-errors-plugin',
10+
setup(build) {
11+
const { onTransform } = getBuildExtensions(build, 'mangle-errors-plugin')
12+
13+
onTransform({ loaders: ['ts', 'tsx'] }, async args => {
14+
const res = babel.transformSync(args.code, {
15+
parserOpts: {
16+
plugins: ['typescript']
17+
},
18+
plugins: [['./scripts/mangleErrors.cjs', { minify: false }]]
19+
})!
20+
return {
21+
code: res.code!,
22+
map: res.map!
23+
}
24+
})
25+
}
26+
}
27+
28+
export default defineConfig(options => {
29+
const commonOptions: Partial<Options> = {
30+
entry: {
31+
redux: 'src/index.ts'
32+
},
33+
esbuildPlugins: [mangleErrorsTransform],
34+
sourcemap: true,
35+
...options
36+
}
37+
38+
return [
39+
// Standard ESM, embedded `process.env.NODE_ENV` checks
40+
{
41+
...commonOptions,
42+
format: ['esm'],
43+
outExtension: () => ({ js: '.mjs' }),
44+
dts: true,
45+
clean: true
46+
},
47+
// Browser-ready ESM, production + minified
48+
{
49+
...commonOptions,
50+
entry: {
51+
'redux.browser': 'src/index.ts'
52+
},
53+
define: {
54+
'process.env.NODE_ENV': JSON.stringify('production')
55+
},
56+
format: ['esm'],
57+
outExtension: () => ({ js: '.mjs' }),
58+
minify: true
59+
},
60+
{
61+
...commonOptions,
62+
format: 'cjs',
63+
outDir: './dist/cjs/',
64+
outExtension: () => ({ js: '.cjs' })
65+
}
66+
]
67+
})

0 commit comments

Comments
 (0)