├── .changeset
├── README.md
└── config.json
├── .github
└── workflows
│ ├── node.js.yml
│ └── release.yml
├── .gitignore
├── .husky
└── pre-commit
├── .prettierignore
├── LICENSE
├── README.md
├── examples
├── with-javascript
│ ├── .gitignore
│ ├── craco.config.js
│ ├── package.json
│ ├── public
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ ├── logo192.png
│ │ ├── logo512.png
│ │ ├── manifest.json
│ │ └── robots.txt
│ └── src
│ │ ├── App.css
│ │ ├── App.jsx
│ │ ├── App.test.jsx
│ │ ├── features
│ │ └── jest-mocks
│ │ │ ├── __mocks__
│ │ │ └── jest-mocks.js
│ │ │ ├── jest-mocks.js
│ │ │ └── jest-mocks.test.js
│ │ ├── index.css
│ │ ├── index.jsx
│ │ ├── logo.svg
│ │ └── setupTests.js
├── with-svgr
│ ├── .gitignore
│ ├── craco.config.js
│ ├── package.json
│ ├── public
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ ├── logo192.png
│ │ ├── logo512.png
│ │ ├── manifest.json
│ │ └── robots.txt
│ └── src
│ │ ├── App.css
│ │ ├── App.jsx
│ │ ├── App.test.jsx
│ │ ├── index.css
│ │ ├── index.jsx
│ │ ├── logo.svg
│ │ └── setupTests.js
└── with-typescript
│ ├── .gitignore
│ ├── craco.config.js
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
│ ├── src
│ ├── App.css
│ ├── App.test.tsx
│ ├── App.tsx
│ ├── features
│ │ └── jest-mocks
│ │ │ ├── __mocks__
│ │ │ └── jest-mocks.ts
│ │ │ ├── jest-mocks.test.ts
│ │ │ └── jest-mocks.ts
│ ├── index.css
│ ├── index.tsx
│ ├── logo.svg
│ ├── react-app-env.d.ts
│ └── setupTests.ts
│ └── tsconfig.json
├── package.json
├── packages
└── craco-esbuild
│ ├── CHANGELOG.md
│ ├── README.md
│ ├── package.json
│ └── src
│ └── index.js
├── pnpm-lock.yaml
└── pnpm-workspace.yaml
/.changeset/README.md:
--------------------------------------------------------------------------------
1 | # Changesets
2 |
3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
4 | with multi-package repos, or single-package repos to help you version and publish your code. You can
5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets)
6 |
7 | We have a quick list of common questions to get you started engaging with this project in
8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
9 |
--------------------------------------------------------------------------------
/.changeset/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://unpkg.com/@changesets/config@1.6.3/schema.json",
3 | "changelog": [
4 | "@changesets/changelog-github",
5 | { "repo": "pradel/create-react-app-esbuild" }
6 | ],
7 | "commit": false,
8 | "linked": [],
9 | "access": "public",
10 | "baseBranch": "main",
11 | "updateInternalDependencies": "patch",
12 | "ignore": []
13 | }
14 |
--------------------------------------------------------------------------------
/.github/workflows/node.js.yml:
--------------------------------------------------------------------------------
1 | name: Node.js CI
2 |
3 | on:
4 | push:
5 | branches: [main]
6 | pull_request:
7 | branches: [main]
8 |
9 | jobs:
10 | # Test default react-scripts to compare time
11 | test-react-scripts:
12 | runs-on: ubuntu-latest
13 |
14 | strategy:
15 | matrix:
16 | node-version: [18.x, 20.x]
17 |
18 | steps:
19 | - uses: actions/checkout@v2
20 |
21 | - uses: pnpm/action-setup@v2
22 | with:
23 | version: 8.15.1
24 |
25 | - name: Use Node.js ${{ matrix.node-version }}
26 | uses: actions/setup-node@v2
27 | with:
28 | node-version: ${{ matrix.node-version }}
29 | cache: 'pnpm'
30 |
31 | - name: Install dependencies
32 | run: pnpm install
33 |
34 | - name: Compile create-react-app examples using react-scripts
35 | run: |
36 | pnpm run --filter "with-*" build-react-scripts
37 |
38 | - name: Test create-react-app examples using react-scripts
39 | run: |
40 | pnpm run --filter "with-*" test-react-scripts
41 |
42 | test:
43 | runs-on: ubuntu-latest
44 |
45 | strategy:
46 | matrix:
47 | node-version: [18.x, 20.x]
48 |
49 | steps:
50 | - uses: actions/checkout@v2
51 |
52 | - uses: pnpm/action-setup@v2
53 | with:
54 | version: 8.15.1
55 |
56 | - name: Use Node.js ${{ matrix.node-version }}
57 | uses: actions/setup-node@v2
58 | with:
59 | node-version: ${{ matrix.node-version }}
60 | cache: 'pnpm'
61 |
62 | - name: Install dependencies
63 | run: pnpm install
64 |
65 | - name: Compile create-react-app examples using craco
66 | run: |
67 | pnpm run --filter "with-*" build
68 |
69 | - name: Test create-react-app examples using craco
70 | run: |
71 | pnpm run --filter "with-*" test
72 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Release
2 |
3 | on:
4 | push:
5 | branches: [main]
6 |
7 | jobs:
8 | release:
9 | name: Release
10 | runs-on: ubuntu-latest
11 | steps:
12 | - name: Checkout Repo
13 | uses: actions/checkout@v2
14 | with:
15 | # This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits
16 | fetch-depth: 0
17 |
18 | - uses: pnpm/action-setup@v2
19 | with:
20 | version: 8.15.1
21 |
22 | - name: Use Node.js 20.x
23 | uses: actions/setup-node@v2
24 | with:
25 | node-version: 20.x
26 | cache: 'pnpm'
27 |
28 | - name: Install dependencies
29 | run: pnpm install
30 |
31 | - name: Create Release Pull Request or Publish to npm
32 | id: changesets
33 | uses: changesets/action@v1
34 | with:
35 | version: pnpm run version
36 | publish: pnpm run release
37 | commit: 'chore: update versions'
38 | title: 'chore: version packages'
39 | env:
40 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
41 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
42 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | . "$(dirname "$0")/_/husky.sh"
3 |
4 | pnpm lint-staged
5 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | build
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Léo Pradel
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 🚀 create-react-app-esbuild 🚀
2 |
3 | Use [esbuild](https://github.com/evanw/esbuild) in your [create-react-app](https://create-react-app.dev/) for faster compilation, development and tests.
4 |
5 | ## Features
6 |
7 | - Replace babel-loader with esbuild during development
8 | - Replace babel-loader with esbuild for faster build time
9 | - Replace terser with esbuild for faster build time
10 | - Replace OptimizeCssAssetsWebpackPlugin with esbuild for faster build time
11 | - Use esbuild when running jest
12 |
13 | ## Getting started
14 |
15 | Follow the [guide](https://github.com/pradel/create-react-app-esbuild/blob/main/packages/craco-esbuild/README.md) to setup your project.
16 |
17 | ## FAQ
18 |
19 | ### Why is it faster?
20 |
21 | Internally create-react-app use babel to compile the javascript / typescript files of your application. By using craco-esbuild, you use the [esbuild](https://github.com/evanw/esbuild) compiler to compile your app instead of babel. esbuild is a super fast javascript / typescript bundler and minifier written in Go.
22 |
23 | ### What is craco and why do I need it?
24 |
25 | [craco](https://github.com/gsoft-inc/craco) (**C**reate **R**eact **A**pp **C**onfiguration **O**verride) is an easy and comprehensible configuration layer for create-react-app. By using craco you can customise the create-react-app configuration without ejecting.
26 |
27 | ## License
28 |
29 | MIT © [Léo Pradel](https://www.leopradel.com/)
30 |
--------------------------------------------------------------------------------
/examples/with-javascript/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/examples/with-javascript/craco.config.js:
--------------------------------------------------------------------------------
1 | const CracoEsbuildPlugin = require('craco-esbuild');
2 |
3 | module.exports = {
4 | plugins: [
5 | {
6 | plugin: CracoEsbuildPlugin,
7 | },
8 | ],
9 | };
10 |
--------------------------------------------------------------------------------
/examples/with-javascript/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "with-javascript",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@babel/plugin-transform-modules-commonjs": "^7.23.3",
7 | "@craco/craco": "7.0.0",
8 | "@testing-library/jest-dom": "^6.3.0",
9 | "@testing-library/react": "^12.1.2",
10 | "@testing-library/user-event": "^13.5.0",
11 | "craco-esbuild": "workspace:craco-esbuild",
12 | "react": "^17.0.2",
13 | "react-dom": "^17.0.2",
14 | "react-scripts": "5.0.0"
15 | },
16 | "scripts": {
17 | "start": "craco start",
18 | "start-react-scripts": "react-scripts start",
19 | "build": "craco build",
20 | "build-react-scripts": "react-scripts build",
21 | "test": "craco test",
22 | "test-react-scripts": "react-scripts test",
23 | "eject": "react-scripts eject"
24 | },
25 | "eslintConfig": {
26 | "extends": [
27 | "react-app",
28 | "react-app/jest"
29 | ]
30 | },
31 | "browserslist": {
32 | "production": [
33 | ">0.2%",
34 | "not dead",
35 | "not op_mini all"
36 | ],
37 | "development": [
38 | "last 1 chrome version",
39 | "last 1 firefox version",
40 | "last 1 safari version"
41 | ]
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/examples/with-javascript/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pradel/create-react-app-esbuild/6a8be4d0b6d9c9b6b569f37b48862ba98f5bb176/examples/with-javascript/public/favicon.ico
--------------------------------------------------------------------------------
/examples/with-javascript/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/examples/with-javascript/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pradel/create-react-app-esbuild/6a8be4d0b6d9c9b6b569f37b48862ba98f5bb176/examples/with-javascript/public/logo192.png
--------------------------------------------------------------------------------
/examples/with-javascript/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pradel/create-react-app-esbuild/6a8be4d0b6d9c9b6b569f37b48862ba98f5bb176/examples/with-javascript/public/logo512.png
--------------------------------------------------------------------------------
/examples/with-javascript/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/examples/with-javascript/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/examples/with-javascript/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/examples/with-javascript/src/App.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import logo from './logo.svg';
3 | import './App.css';
4 |
5 | function App() {
6 | return (
7 |
23 | );
24 | }
25 |
26 | export default App;
27 |
--------------------------------------------------------------------------------
/examples/with-javascript/src/App.test.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render, screen } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | render();
7 | const linkElement = screen.getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/examples/with-javascript/src/features/jest-mocks/__mocks__/jest-mocks.js:
--------------------------------------------------------------------------------
1 | export const jestMockWorking = true;
2 |
--------------------------------------------------------------------------------
/examples/with-javascript/src/features/jest-mocks/jest-mocks.js:
--------------------------------------------------------------------------------
1 | export const jestMockWorking = false;
2 |
--------------------------------------------------------------------------------
/examples/with-javascript/src/features/jest-mocks/jest-mocks.test.js:
--------------------------------------------------------------------------------
1 | import { jestMockWorking } from './jest-mocks';
2 |
3 | jest.mock('./jest-mocks');
4 |
5 | test('Value should be true if mocks is working', () => {
6 | expect(jestMockWorking).toBe(true);
7 | });
8 |
--------------------------------------------------------------------------------
/examples/with-javascript/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/examples/with-javascript/src/index.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 |
6 | ReactDOM.render(
7 |
8 |
9 | ,
10 | document.getElementById('root')
11 | );
12 |
--------------------------------------------------------------------------------
/examples/with-javascript/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/with-javascript/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/examples/with-svgr/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/examples/with-svgr/craco.config.js:
--------------------------------------------------------------------------------
1 | const CracoEsbuildPlugin = require('craco-esbuild');
2 |
3 | module.exports = {
4 | plugins: [
5 | {
6 | plugin: CracoEsbuildPlugin,
7 | options: {
8 | enableSvgr: true,
9 | },
10 | },
11 | ],
12 | };
13 |
--------------------------------------------------------------------------------
/examples/with-svgr/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "with-svgr",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@craco/craco": "7.0.0",
7 | "@testing-library/jest-dom": "^6.3.0",
8 | "@testing-library/react": "^12.1.2",
9 | "@testing-library/user-event": "^13.5.0",
10 | "craco-esbuild": "workspace:craco-esbuild",
11 | "react": "^17.0.2",
12 | "react-dom": "^17.0.2",
13 | "react-scripts": "5.0.0"
14 | },
15 | "scripts": {
16 | "start": "craco start",
17 | "start-react-scripts": "react-scripts start",
18 | "build": "craco build",
19 | "build-react-scripts": "react-scripts build",
20 | "test": "craco test",
21 | "test-react-scripts": "react-scripts test",
22 | "eject": "react-scripts eject"
23 | },
24 | "eslintConfig": {
25 | "extends": [
26 | "react-app",
27 | "react-app/jest"
28 | ]
29 | },
30 | "browserslist": {
31 | "production": [
32 | ">0.2%",
33 | "not dead",
34 | "not op_mini all"
35 | ],
36 | "development": [
37 | "last 1 chrome version",
38 | "last 1 firefox version",
39 | "last 1 safari version"
40 | ]
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/examples/with-svgr/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pradel/create-react-app-esbuild/6a8be4d0b6d9c9b6b569f37b48862ba98f5bb176/examples/with-svgr/public/favicon.ico
--------------------------------------------------------------------------------
/examples/with-svgr/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/examples/with-svgr/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pradel/create-react-app-esbuild/6a8be4d0b6d9c9b6b569f37b48862ba98f5bb176/examples/with-svgr/public/logo192.png
--------------------------------------------------------------------------------
/examples/with-svgr/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pradel/create-react-app-esbuild/6a8be4d0b6d9c9b6b569f37b48862ba98f5bb176/examples/with-svgr/public/logo512.png
--------------------------------------------------------------------------------
/examples/with-svgr/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/examples/with-svgr/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/examples/with-svgr/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/examples/with-svgr/src/App.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { ReactComponent as Logo } from './logo.svg';
3 | import './App.css';
4 |
5 | function App() {
6 | return (
7 |
23 | );
24 | }
25 |
26 | export default App;
27 |
--------------------------------------------------------------------------------
/examples/with-svgr/src/App.test.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render, screen } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | render();
7 | const linkElement = screen.getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/examples/with-svgr/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/examples/with-svgr/src/index.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 |
6 | ReactDOM.render(
7 |
8 |
9 | ,
10 | document.getElementById('root')
11 | );
12 |
--------------------------------------------------------------------------------
/examples/with-svgr/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/with-svgr/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/examples/with-typescript/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/examples/with-typescript/craco.config.js:
--------------------------------------------------------------------------------
1 | const CracoEsbuildPlugin = require('craco-esbuild');
2 |
3 | module.exports = {
4 | plugins: [
5 | {
6 | plugin: CracoEsbuildPlugin,
7 | },
8 | ],
9 | };
10 |
--------------------------------------------------------------------------------
/examples/with-typescript/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "with-typescript",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@babel/plugin-transform-modules-commonjs": "^7.23.3",
7 | "@craco/craco": "7.0.0",
8 | "@testing-library/jest-dom": "^6.3.0",
9 | "@testing-library/react": "^12.1.2",
10 | "@testing-library/user-event": "^13.5.0",
11 | "@types/jest": "^28.0.0",
12 | "@types/node": "^18.19.18",
13 | "@types/react": "^17.0.38",
14 | "@types/react-dom": "^17.0.11",
15 | "craco-esbuild": "workspace:craco-esbuild",
16 | "react": "^17.0.2",
17 | "react-dom": "^17.0.2",
18 | "react-scripts": "5.0.0",
19 | "typescript": "^4.5.4"
20 | },
21 | "scripts": {
22 | "start": "craco start",
23 | "start-react-scripts": "react-scripts start",
24 | "build": "craco build",
25 | "build-react-scripts": "react-scripts build",
26 | "test": "craco test",
27 | "test-react-scripts": "react-scripts test",
28 | "eject": "react-scripts eject"
29 | },
30 | "eslintConfig": {
31 | "extends": [
32 | "react-app",
33 | "react-app/jest"
34 | ]
35 | },
36 | "browserslist": {
37 | "production": [
38 | ">0.2%",
39 | "not dead",
40 | "not op_mini all"
41 | ],
42 | "development": [
43 | "last 1 chrome version",
44 | "last 1 firefox version",
45 | "last 1 safari version"
46 | ]
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/examples/with-typescript/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pradel/create-react-app-esbuild/6a8be4d0b6d9c9b6b569f37b48862ba98f5bb176/examples/with-typescript/public/favicon.ico
--------------------------------------------------------------------------------
/examples/with-typescript/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/examples/with-typescript/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pradel/create-react-app-esbuild/6a8be4d0b6d9c9b6b569f37b48862ba98f5bb176/examples/with-typescript/public/logo192.png
--------------------------------------------------------------------------------
/examples/with-typescript/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pradel/create-react-app-esbuild/6a8be4d0b6d9c9b6b569f37b48862ba98f5bb176/examples/with-typescript/public/logo512.png
--------------------------------------------------------------------------------
/examples/with-typescript/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/examples/with-typescript/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/examples/with-typescript/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/examples/with-typescript/src/App.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render, screen } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | render();
7 | const linkElement = screen.getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/examples/with-typescript/src/App.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import logo from './logo.svg';
3 | import './App.css';
4 |
5 | function App() {
6 | return (
7 |
23 | );
24 | }
25 |
26 | export default App;
27 |
--------------------------------------------------------------------------------
/examples/with-typescript/src/features/jest-mocks/__mocks__/jest-mocks.ts:
--------------------------------------------------------------------------------
1 | export const jestMockWorking = true;
2 |
--------------------------------------------------------------------------------
/examples/with-typescript/src/features/jest-mocks/jest-mocks.test.ts:
--------------------------------------------------------------------------------
1 | import { jestMockWorking } from './jest-mocks';
2 |
3 | jest.mock('./jest-mocks');
4 |
5 | test('Value should be true if mocks is working', () => {
6 | expect(jestMockWorking).toBe(true);
7 | });
8 |
--------------------------------------------------------------------------------
/examples/with-typescript/src/features/jest-mocks/jest-mocks.ts:
--------------------------------------------------------------------------------
1 | export const jestMockWorking = false;
2 |
--------------------------------------------------------------------------------
/examples/with-typescript/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/examples/with-typescript/src/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 |
6 | ReactDOM.render(
7 |
8 |
9 | ,
10 | document.getElementById('root')
11 | );
12 |
--------------------------------------------------------------------------------
/examples/with-typescript/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/with-typescript/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/examples/with-typescript/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/examples/with-typescript/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "esModuleInterop": true,
8 | "allowSyntheticDefaultImports": true,
9 | "strict": true,
10 | "forceConsistentCasingInFileNames": true,
11 | "noFallthroughCasesInSwitch": true,
12 | "module": "esnext",
13 | "moduleResolution": "node",
14 | "resolveJsonModule": true,
15 | "isolatedModules": true,
16 | "noEmit": true,
17 | "jsx": "react-jsx",
18 | "types": ["jest", "@testing-library/jest-dom"]
19 | },
20 | "include": ["src"]
21 | }
22 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "scripts": {
4 | "prettier": "prettier --write \"**/*.{js,ts,tsx,css,scss,json,md,mdx,yml}\"",
5 | "version": "pnpm changeset version && pnpm install --lockfile-only",
6 | "release": "pnpm changeset publish",
7 | "prepare": "husky install"
8 | },
9 | "prettier": {
10 | "singleQuote": true
11 | },
12 | "engines": {
13 | "node": ">=18.0.0"
14 | },
15 | "lint-staged": {
16 | "*.{js,ts,tsx,css,scss,json,md,mdx,yml}": [
17 | "prettier --write",
18 | "git add"
19 | ]
20 | },
21 | "devDependencies": {
22 | "@changesets/changelog-github": "0.4.2",
23 | "@changesets/cli": "2.19.0",
24 | "husky": "7.0.4",
25 | "lint-staged": "12.1.7",
26 | "prettier": "2.5.1"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/packages/craco-esbuild/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## 0.6.1
4 |
5 | ### Patch Changes
6 |
7 | - [#77](https://github.com/pradel/create-react-app-esbuild/pull/77) [`14c3d80`](https://github.com/pradel/create-react-app-esbuild/commit/14c3d80ee8799615d23dd47075c1752fcc1742c4) Thanks [@pradel](https://github.com/pradel)! - Fix invalid craco version in package.json.
8 |
9 | ## 0.6.0
10 |
11 | ### Minor Changes
12 |
13 | - [#73](https://github.com/pradel/create-react-app-esbuild/pull/73) [`935c2f9`](https://github.com/pradel/create-react-app-esbuild/commit/935c2f9ed35c9ef37ad3750652ad163508c50cb8) Thanks [@Crecket](https://github.com/Crecket)! - Updated esbuild-loader to v4 and craco to v7.
14 |
15 | ## 0.5.2
16 |
17 | ### Patch Changes
18 |
19 | - [#63](https://github.com/pradel/create-react-app-esbuild/pull/63) [`8aa74cd`](https://github.com/pradel/create-react-app-esbuild/commit/8aa74cdce93d19955ac2050fbf6512981a9eaa0b) Thanks [@jiejasonliu](https://github.com/jiejasonliu)! - Include @craco/craco@7.0.0-alpha.* versions in peerDependencies
20 |
21 | ## 0.5.1
22 |
23 | ### Patch Changes
24 |
25 | - [#57](https://github.com/pradel/create-react-app-esbuild/pull/57) [`615f523`](https://github.com/pradel/create-react-app-esbuild/commit/615f52337d8661b7307768f0cb5665b7e678559c) Thanks [@ottob](https://github.com/ottob)! - Add craco 7 to peerDependencies
26 |
27 | ## 0.5.0
28 |
29 | ### Minor Changes
30 |
31 | - [#48](https://github.com/pradel/create-react-app-esbuild/pull/48) [`f276f85`](https://github.com/pradel/create-react-app-esbuild/commit/f276f850732c1faf8e5cb6fd0471f66c691f9ba2) Thanks [@pradel](https://github.com/pradel)! - 🚀 create-react-app 5 is now supported 🚀
32 |
33 | ## Breaking Changes
34 |
35 | - Removed the `enableSvgr` and `svgrOptions` options. Svgr is now working out of the box.
36 | - Drop support for CRA 3 and 4. As many underlying libraries have changed, CRA 4 and 3 are no longer supported. Check the [CRA changelog](https://github.com/facebook/create-react-app/releases/tag/v5.0.0) to see what changed.
37 |
38 | ## Migrating from 0.4.X to 0.5.X
39 |
40 | - You will first need to migrate your project to CRA 5. See the CRA [Migration guide](https://github.com/facebook/create-react-app/releases/tag/v5.0.0) for more information.
41 | - Upgrade `craco-esbuild` to version 0.5.0 or higher in your project.
42 | - If you are using `enableSvgr` or `svgrOptions` you can remove them from the `craco.config.js` file. Svgr is now working out of the box.
43 |
44 | ## 0.4.5
45 |
46 | ### Patch Changes
47 |
48 | - [#49](https://github.com/pradel/create-react-app-esbuild/pull/49) [`9e09177`](https://github.com/pradel/create-react-app-esbuild/commit/9e09177ca75051749705b9b957c07b01aabfd0b9) Thanks [@pradel](https://github.com/pradel)! - Use require.resolve to import the '@svgr/webpack' loader, this solve an issue that monorepo can have.
49 |
50 | ## 0.4.4
51 |
52 | ### Patch Changes
53 |
54 | - [#46](https://github.com/pradel/create-react-app-esbuild/pull/46) [`109a742`](https://github.com/pradel/create-react-app-esbuild/commit/109a7429b780c2c6dd1f55d12ae11e3ca72ed36a) Thanks [@pradel](https://github.com/pradel)! - Automate release process.
55 |
56 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
57 |
58 | ### [0.4.3](https://github.com/pradel/create-react-app-esbuild/compare/v0.4.2...v0.4.3) (2021-12-14)
59 |
60 | ### Features
61 |
62 | - add `svgrOptions` to customize svgr plugin behavior ([#44](https://github.com/pradel/create-react-app-esbuild/issues/44)) ([4ebde9f](https://github.com/pradel/create-react-app-esbuild/commit/4ebde9fd73a0f243531a4570feb7873f8cacc55e))
63 |
64 | ### [0.4.2](https://github.com/pradel/create-react-app-esbuild/compare/v0.4.1...v0.4.2) (2021-10-12)
65 |
66 | ### Features
67 |
68 | - replace minifier only when used ([#42](https://github.com/pradel/create-react-app-esbuild/issues/42)) ([7453334](https://github.com/pradel/create-react-app-esbuild/commit/745333410391d4bb97fef76d21c0afbc2e65b631))
69 |
70 | ### [0.4.1](https://github.com/pradel/create-react-app-esbuild/compare/v0.4.0...v0.4.1) (2021-09-22)
71 |
72 | ### Bug Fixes
73 |
74 | - compatability with node 12 ([#40](https://github.com/pradel/create-react-app-esbuild/issues/40)) ([269dd30](https://github.com/pradel/create-react-app-esbuild/commit/269dd3055e59930ca4534aa7ab124f02883823e6))
75 |
76 | ## [0.4.0](https://github.com/pradel/create-react-app-esbuild/compare/v0.3.4...v0.4.0) (2021-09-06)
77 |
78 | ### ⚠ BREAKING CHANGES
79 |
80 | - add esbuild css minification (#36)
81 |
82 | ### Features
83 |
84 | - add esbuild css minification ([#36](https://github.com/pradel/create-react-app-esbuild/issues/36)) ([35214fb](https://github.com/pradel/create-react-app-esbuild/commit/35214fb9325f52f7a4406afc7c9359650aa820da))
85 |
86 | ### Miscellaneous Chores
87 |
88 | - upgrade deps ([#37](https://github.com/pradel/create-react-app-esbuild/issues/37)) ([2d7079e](https://github.com/pradel/create-react-app-esbuild/commit/2d7079e81269bed793b447d6c854e53dd314afc2))
89 |
90 | ### [0.3.4](https://github.com/pradel/create-react-app-esbuild/compare/v0.3.3...v0.3.4) (2021-08-16)
91 |
92 | ### Features
93 |
94 | - add `esbuildJestOptions` to override esbuild-jest's options ([#34](https://github.com/pradel/create-react-app-esbuild/issues/34)) ([cbd7d03](https://github.com/pradel/create-react-app-esbuild/commit/cbd7d031011f5ce10f8217c06868998ddf9f5af0))
95 |
96 | ### Miscellaneous Chores
97 |
98 | - prettier ([6b8e8e4](https://github.com/pradel/create-react-app-esbuild/commit/6b8e8e469ed71b9812d8553260b952cee11e2edd))
99 |
100 | ### [0.3.3](https://github.com/pradel/create-react-app-esbuild/compare/v0.3.2...v0.3.3) (2021-07-25)
101 |
102 | ### Documentation
103 |
104 | - improve example for typescript users ([2517cbc](https://github.com/pradel/create-react-app-esbuild/commit/2517cbcaf965a339002c2fefa7368b12a90ea58c))
105 |
106 | ### [0.3.2](https://github.com/pradel/create-react-app-esbuild/compare/v0.3.1...v0.3.2) (2021-04-28)
107 |
108 | ### Miscellaneous Chores
109 |
110 | - upgrade deps ([#25](https://github.com/pradel/create-react-app-esbuild/issues/25)) ([f27f4e9](https://github.com/pradel/create-react-app-esbuild/commit/f27f4e9c4ad5dcb5a0e51106e0d667c338bda372))
111 |
112 | ### [0.3.1](https://github.com/pradel/create-react-app-esbuild/compare/v0.3.0...v0.3.1) (2021-03-16)
113 |
114 | ### Bug Fixes
115 |
116 | - remove ESBuildPlugin import. ([#21](https://github.com/pradel/create-react-app-esbuild/issues/21)) ([2e25db5](https://github.com/pradel/create-react-app-esbuild/commit/2e25db51fd8678fcd8475a7abb5d75140ec0d0bb))
117 |
118 | ## [0.3.0](https://github.com/pradel/create-react-app-esbuild/compare/v0.2.1...v0.3.0) (2021-03-04)
119 |
120 | ### Features
121 |
122 | - add svgr support ([#14](https://github.com/pradel/create-react-app-esbuild/issues/14)) ([1cac975](https://github.com/pradel/create-react-app-esbuild/commit/1cac975b3e487912e595ad803cf773e5b58de974))
123 |
124 | ### [0.2.1](https://github.com/pradel/create-react-app-esbuild/compare/v0.2.0...v0.2.1) (2021-02-27)
125 |
126 | ### Bug Fixes
127 |
128 | - upgrade esbuild-jest to support jest mocks ([#16](https://github.com/pradel/create-react-app-esbuild/issues/16)) ([68dae43](https://github.com/pradel/create-react-app-esbuild/commit/68dae4360a01e692461d08b673ce61c8c196b777))
129 |
130 | ### Miscellaneous Chores
131 |
132 | - upgrade esbuild-jest to 0.4 ([#13](https://github.com/pradel/create-react-app-esbuild/issues/13)) ([7db4e35](https://github.com/pradel/create-react-app-esbuild/commit/7db4e35a36f991f9e405d664b510875e2ed08a0c))
133 |
134 | ### Documentation
135 |
136 | - document `includePaths` option ([49a9b1d](https://github.com/pradel/create-react-app-esbuild/commit/49a9b1dc6f10422cc5c413196c496431629cef3b))
137 |
138 | ## 0.2.0 (2021-01-18)
139 |
140 | ### Features
141 |
142 | - custom include paths and esbuild jest config ([#5](https://github.com/pradel/create-react-app-esbuild/issues/5)) ([3438f09](https://github.com/pradel/create-react-app-esbuild/commit/3438f092f66e454119b03324e6387dbbe5a0261f))
143 | - first version ([#1](https://github.com/pradel/create-react-app-esbuild/issues/1)) ([318ace0](https://github.com/pradel/create-react-app-esbuild/commit/318ace0957961e2482d45e041fc969a6bbaf4282))
144 |
145 | ### Miscellaneous Chores
146 |
147 | - automate release ([#10](https://github.com/pradel/create-react-app-esbuild/issues/10)) ([4b9048c](https://github.com/pradel/create-react-app-esbuild/commit/4b9048cb353d2897b21d4b0fea3bcbfdca7a56f1))
148 | - fix plugin name ([87442e0](https://github.com/pradel/create-react-app-esbuild/commit/87442e01067819b857766dfe9abd787a9ea8c61a))
149 | - improve documentation ([efd3ffe](https://github.com/pradel/create-react-app-esbuild/commit/efd3ffed875aced377970ff36fb0271ce41c69a6))
150 | - update esbuild-loader to 2.8.0 ([#9](https://github.com/pradel/create-react-app-esbuild/issues/9)) ([f5470af](https://github.com/pradel/create-react-app-esbuild/commit/f5470af7298f5a8b078447a20c5991e554b4bdac))
151 | - upgrade deps ([#3](https://github.com/pradel/create-react-app-esbuild/issues/3)) ([682f8c3](https://github.com/pradel/create-react-app-esbuild/commit/682f8c352fe670964e88e05897e9b37bd0c82cbd))
152 |
--------------------------------------------------------------------------------
/packages/craco-esbuild/README.md:
--------------------------------------------------------------------------------
1 | # 🚀 craco-esbuild 🚀
2 |
3 | Use [esbuild](https://github.com/evanw/esbuild) in your [create-react-app](https://create-react-app.dev/) with [craco](https://github.com/gsoft-inc/craco) for faster compilation, development and tests.
4 |
5 | ## Features
6 |
7 | - Replace babel-loader with esbuild during development
8 | - Replace babel-loader with esbuild for faster build time
9 | - Replace terser with esbuild for faster build time
10 | - Replace OptimizeCssAssetsWebpackPlugin with esbuild for faster build time
11 | - Use esbuild when running jest
12 |
13 | ## Installation
14 |
15 | Run the following command to install `craco-esbuild` in your project:
16 |
17 | ```sh
18 | yarn add --dev craco-esbuild @craco/craco
19 | ```
20 | OR
21 | ```sh
22 | npm install --save-dev craco-esbuild @craco/craco
23 | ```
24 |
25 | ## Usage
26 |
27 | Add this configuration to your `craco.config.js` configuration file:
28 |
29 | ```js
30 | // craco.config.js
31 | const CracoEsbuildPlugin = require('craco-esbuild');
32 |
33 | module.exports = {
34 | plugins: [{ plugin: CracoEsbuildPlugin }],
35 | };
36 | ```
37 |
38 | To use `craco` instead of `react-scripts` to manage our application, edit the `scripts` section of your `package.json`.
39 |
40 | ```diff
41 | /* package.json */
42 |
43 | "scripts": {
44 | - "start": "react-scripts start",
45 | + "start": "craco start",
46 | - "build": "react-scripts build",
47 | + "build": "craco build"
48 | - "test": "react-scripts test",
49 | + "test": "craco test"
50 | }
51 | ```
52 |
53 | ## Configuration
54 |
55 | You can configure the options of the plugin by passing an `options` object.
56 |
57 | - `esbuildLoaderOptions`: customise the options passed down to the `esbuild` loader. _Note: This will be used only by webpack_
58 | - `esbuildMinimizerOptions`: customise the options passed down to `ESBuildMinifyPlugin`. _Note: This will be used only by webpack_
59 | - `includePaths`: include external directories in loader.
60 | - `skipEsbuildJest`: Avoid using `esbuild-jest` for jest configuration. Could be useful to avoid compatibility issues with transpiling tests.
61 | - `esbuildJestOptions`: customise the [options](https://github.com/aelbore/esbuild-jest#setting-up-jest-config-file-with-transformoptions) passed down to the `esbuild-jest` transformer.
62 |
63 | For example add this configuration to your `craco.config.js` configuration file:
64 |
65 | ```js
66 | // craco.config.js
67 | const CracoEsbuildPlugin = require('craco-esbuild');
68 |
69 | module.exports = {
70 | plugins: [
71 | {
72 | plugin: CracoEsbuildPlugin,
73 | options: {
74 | includePaths: ['/external/dir/with/components'], // Optional. If you want to include components which are not in src folder
75 | esbuildLoaderOptions: {
76 | // Optional. Defaults to auto-detect loader.
77 | loader: 'jsx', // Set the value to 'tsx' if you use typescript
78 | target: 'es2015',
79 | },
80 | esbuildMinimizerOptions: {
81 | // Optional. Defaults to:
82 | target: 'es2015',
83 | css: true, // if true, OptimizeCssAssetsWebpackPlugin will also be replaced by esbuild.
84 | },
85 | skipEsbuildJest: false, // Optional. Set to true if you want to use babel for jest tests,
86 | esbuildJestOptions: {
87 | loaders: {
88 | '.ts': 'ts',
89 | '.tsx': 'tsx',
90 | },
91 | },
92 | },
93 | },
94 | ],
95 | };
96 | ```
97 |
98 | ## License
99 |
100 | MIT © [Léo Pradel](https://www.leopradel.com/)
101 |
--------------------------------------------------------------------------------
/packages/craco-esbuild/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "craco-esbuild",
3 | "version": "0.6.1",
4 | "main": "src/index.js",
5 | "repository": "https://github.com/pradel/create-react-app-esbuild.git",
6 | "author": "Leo Pradel ",
7 | "license": "MIT",
8 | "files": [
9 | "src"
10 | ],
11 | "peerDependencies": {
12 | "@craco/craco": "^7.0.0",
13 | "react-scripts": "^5.0.0"
14 | },
15 | "dependencies": {
16 | "esbuild-jest": "0.5.0",
17 | "esbuild-loader": "^4.0.1"
18 | },
19 | "devDependencies": {
20 | "@craco/craco": "7.0.0",
21 | "react-scripts": "5.0.0"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/packages/craco-esbuild/src/index.js:
--------------------------------------------------------------------------------
1 | const { loaderByName, removeLoaders, addAfterLoader } = require('@craco/craco');
2 | const { EsbuildPlugin } = require('esbuild-loader');
3 |
4 | const removeMinimizer = (webpackConfig, name) => {
5 | const idx = webpackConfig.optimization.minimizer.findIndex(
6 | (m) => m.constructor.name === name
7 | );
8 | webpackConfig.optimization.minimizer.splice(idx, 1);
9 | };
10 |
11 | const replaceMinimizer = (webpackConfig, name, minimizer) => {
12 | const idx = webpackConfig.optimization.minimizer.findIndex(
13 | (m) => m.constructor.name === name
14 | );
15 | idx > -1 && webpackConfig.optimization.minimizer.splice(idx, 1, minimizer);
16 | };
17 |
18 | module.exports = {
19 | /**
20 | * To process the js/ts files we replace the babel-loader with the esbuild-loader
21 | */
22 | overrideWebpackConfig: ({
23 | webpackConfig,
24 | pluginOptions,
25 | context: { paths },
26 | }) => {
27 | const esbuildLoaderOptions =
28 | pluginOptions && pluginOptions.esbuildLoaderOptions;
29 |
30 | // add includePaths custom option, for including files/components in other folders than src
31 | // Used as in addition to paths.appSrc, optional parameter.
32 | const optionalIncludes =
33 | (pluginOptions && pluginOptions.includePaths) || [];
34 |
35 | // add esbuild-loader
36 | addAfterLoader(webpackConfig, loaderByName('babel-loader'), {
37 | test: /\.(js|mjs|jsx|ts|tsx)$/,
38 | include: [paths.appSrc, ...optionalIncludes],
39 | loader: require.resolve('esbuild-loader'),
40 | options: esbuildLoaderOptions
41 | ? esbuildLoaderOptions
42 | : {
43 | target: 'es2015',
44 | },
45 | });
46 |
47 | // remove the babel loaders
48 | removeLoaders(webpackConfig, loaderByName('babel-loader'));
49 |
50 | // Replace terser with esbuild
51 | const minimizerOptions = (pluginOptions || {}).esbuildMinimizerOptions || {
52 | target: 'es2015',
53 | css: true,
54 | };
55 | replaceMinimizer(
56 | webpackConfig,
57 | 'TerserPlugin',
58 | new EsbuildPlugin(minimizerOptions)
59 | );
60 | // remove the css OptimizeCssAssetsWebpackPlugin
61 | if (minimizerOptions.css) {
62 | removeMinimizer(webpackConfig, 'OptimizeCssAssetsWebpackPlugin');
63 | }
64 | return webpackConfig;
65 | },
66 |
67 | /**
68 | * To process the js/ts files we replace the babel-loader with the esbuild jest loader
69 | */
70 | overrideJestConfig: ({ jestConfig, pluginOptions }) => {
71 | if (pluginOptions && pluginOptions.skipEsbuildJest) return jestConfig;
72 |
73 | const defaultEsbuildJestOptions = {
74 | loaders: {
75 | '.js': 'jsx',
76 | '.test.js': 'jsx',
77 | '.ts': 'tsx',
78 | '.test.ts': 'tsx',
79 | },
80 | };
81 |
82 | const esbuildJestOptions =
83 | (pluginOptions && pluginOptions.esbuildJestOptions) ||
84 | defaultEsbuildJestOptions;
85 |
86 | // Replace babel transform with esbuild
87 | // babelTransform is first transformer key
88 | /*
89 | transform:
90 | {
91 | '^.+\\.(js|jsx|mjs|cjs|ts|tsx)$': 'node_modules\\react-scripts\\config\\jest\\babelTransform.js',
92 | '^.+\\.css$': 'node_modules\\react-scripts\\config\\jest\\cssTransform.js',
93 | '^(?!.*\\.(js|jsx|mjs|cjs|ts|tsx|css|json)$)': 'node_modules\\react-scripts\\config\\jest\\fileTransform.js'
94 | }
95 | */
96 | const babelKey = Object.keys(jestConfig.transform)[0];
97 |
98 | // We replace babelTransform and add loaders to esbuild-jest
99 | jestConfig.transform[babelKey] = [
100 | require.resolve('esbuild-jest'),
101 | esbuildJestOptions,
102 | ];
103 |
104 | // Adds loader to all other transform options (2 in this case: cssTransform and fileTransform)
105 | // Reason for this is esbuild-jest plugin. It considers only loaders or other options from the last transformer
106 | // You can see it for yourself in: /node_modules/esbuild-jest/esbuid-jest.js:21 getOptions method
107 | // also in process method line 32 gives empty loaders, because options is already empty object
108 | // Issue reported here: https://github.com/aelbore/esbuild-jest/issues/18
109 | Object.keys(jestConfig.transform).forEach((key) => {
110 | if (babelKey === key) return; // ebuild-jest transform, already has loader
111 |
112 | // Checks if value is array, usually it's not
113 | // Our example is above on 70-72 lines. Usually default is: {"\\.[jt]sx?$": "babel-jest"}
114 | // (https://jestjs.io/docs/en/configuration#transform-objectstring-pathtotransformer--pathtotransformer-object)
115 | // But we have to cover all the cases
116 | if (
117 | Array.isArray(jestConfig.transform[key]) &&
118 | jestConfig.transform[key].length === 1
119 | ) {
120 | jestConfig.transform[key].push(esbuildJestOptions);
121 | } else {
122 | jestConfig.transform[key] = [
123 | jestConfig.transform[key],
124 | esbuildJestOptions,
125 | ];
126 | }
127 | });
128 |
129 | return jestConfig;
130 | },
131 | };
132 |
--------------------------------------------------------------------------------
/pnpm-workspace.yaml:
--------------------------------------------------------------------------------
1 | packages:
2 | - "packages/**"
3 | - "examples/**"
4 |
--------------------------------------------------------------------------------