Skip to content

Commit

Permalink
refactor: improve algorithm (#10)
Browse files Browse the repository at this point in the history
* refactor: improve algorithm, cleanup pkg

* fix: only mutate JSX files

* refactor: remove Canvas extend, improve test coverage

* chore: skiplibcheck for vitest

* fix: don't annotate anonymous extend

* chore: update snapshot

* chore: nits

* Update README.md

Co-authored-by: Umar Ahmed <umar.ahmed1998@gmail.com>

---------

Co-authored-by: Umar Ahmed <umar.ahmed1998@gmail.com>
  • Loading branch information
CodyJasonBennett and umar-ahmed committed Oct 21, 2023
1 parent 661b64e commit be04652
Show file tree
Hide file tree
Showing 28 changed files with 1,523 additions and 4,680 deletions.
5 changes: 0 additions & 5 deletions .codesandbox/ci.json

This file was deleted.

35 changes: 14 additions & 21 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,29 +1,22 @@
name: CI

on:
push:
branches: [ main ]
pull_request: {}
branches: [main]
pull_request:
branches: [main]

jobs:
build:

build-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2

strategy:
matrix:
node-version: [14.x, 16.x]
- name: Install dependencies
run: yarn install

steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
cache: 'yarn'
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Build package
run: yarn build
- name: Run tests
run: yarn test
- name: Check build health
run: yarn build

- name: Run tests
run: yarn test
112 changes: 10 additions & 102 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,104 +1,12 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# TypeScript v1 declaration files
typings/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
.env.test

# parcel-bundler cache (https://parceljs.org/)
.cache

# Next.js build output
.next

# Nuxt.js build / generate output
.nuxt
.DS_Store
node_modules
dist

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and *not* Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
3 changes: 0 additions & 3 deletions .npmignore

This file was deleted.

6 changes: 0 additions & 6 deletions @types/babel-helper-module-imports.d.ts

This file was deleted.

1 change: 0 additions & 1 deletion @types/babel-plugin-syntax-jsx.d.ts

This file was deleted.

2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2021 Poimandres
Copyright (c) 2021-2023 Poimandres

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
131 changes: 7 additions & 124 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,133 +1,16 @@
# react-three-babel

[![Version](https://img.shields.io/npm/v/@react-three/babel?style=flat&colorA=000000&colorB=000000)](https://www.npmjs.com/package/@react-three/babel)
[![Version](https://img.shields.io/npm/v/@react-three/babel?style=flat&colorA=000000&colorB=000000)](https://npmjs.com/@react-three/babel)

A Babel plugin that automatically builds the `extend` catalogue of known native Three.js elements which enables granular usage of Three.js and therefore tree shaking.

It is meant to be used with the new [`createRoot` API](https://docs.pmnd.rs/react-three-fiber/api/canvas#custom-canvas) added in v8 of `@react-three/fiber`, and **will NOT reduce bundle size if using the `Canvas` component ([Read more below](#limitations))!**

- [Install](#install)
- [Usage](#usage)
- [Default](#default)
- [Custom import sources](#custom-import-sources)
- [How it Works](#how-it-works)
- [Limitations](#limitations)

## Install
A Babel plugin for [tree-shaking three.js via JSX](https://docs.pmnd.rs/react-three-fiber/api/canvas#tree-shaking).

```bash
npm install --save-dev @react-three/babel
```

## Usage

### Default

```javascript babel.config.js
module.exports = {
plugins: ["module:@react-three/babel"],
};
```

**In**

```jsx
import { createRoot } from "@react-three/fiber";

createRoot(canvasNode).render(
<mesh>
<boxGeometry />
<meshStandardMaterial />
</mesh>
);
```

**Out**

```jsx
import { createRoot, extend } from "@react-three/fiber";
import {
Mesh as _Mesh,
BoxGeometry as _BoxGeometry,
MeshStandardMaterial as _MeshStandardMaterial,
} from "three";

extend({
Mesh: _Mesh,
BoxGeometry: _BoxGeometry,
MeshStandardMaterial: _MeshStandardMaterial,
});

createRoot(canvasNode).render(
<mesh>
<boxGeometry />
<meshStandardMaterial />
</mesh>
);
```

### Custom import sources

```javascript babel.config.js
module.exports = {
plugins: [
[
"module:@react-three/babel",
{
importSources: ["three", "three-stdlib"], // default: ["three"]
},
],
],
};
```

**In**

```jsx
import { createRoot } from "@react-three/fiber";

createRoot(canvasNode).render(<orbitControls />);
```

**Out**

```jsx
import { createRoot, extend } from "@react-three/fiber";
import { OrbitControls as _OrbitControls } from "three-stdlib";

extend({ OrbitControls: _OrbitControls });

createRoot(canvasNode).render(<orbitControls />);
```

## How it Works

The plugin starts by looking at all the JSX elements that you include in your source
code files (ex. `<h1/>`, `<p/>`, `<ambientLight/>`, etc.). If any of them match an import
from the `three` namespace (or `importSources`, as shown in example above), then it is
added to a set.

Once all the JSX elements in a file are examined, the plugin adds the following imports to that file:

- Import `extend` function from `@react-three/fiber`
- For each name in the set, a named import from the `three` namespace (ex. `import { Mesh } from 'three'`)

Finally, it adds a call to `extend` with the named imports.

## Limitations

This plugin will currently only help reduce the bundle size of your application when using the [`createRoot` API](https://docs.pmnd.rs/react-three-fiber/api/canvas#custom-canvas) added in v8 of `@react-three/fiber`. If you are using the `<Canvas />` component instead, using this Babel plugin will not help reduce bundle size because the `<Canvas />` component automatically extends the entire Three.js component catalogue [here in the code](https://github.com/pmndrs/react-three-fiber/blob/f3d92751d1c22533f10879eb7fd6bb075c674c46/packages/fiber/src/web/Canvas.tsx#L65-L68).

This plugin doesn't do anything special when it comes to making your bundle size smaller. It will help reduce the size compared to extending the entire Three.js component catalogue (ex. using `extend(THREE)`). However, don't expect to get huge bundle size savings as there are some parts of Three.js that are not fully tree-shakable at the time of writing. With that said, you may find [this bundler plugin](https://github.com/yushijinhun/three-minifier) helpful in reducing Three.js' contribution to your bundle size further.

This plugin relies on static analysis of JSX identifiers, which means that **if you wrap any elements or generate elements dynamically, they will not be picked up by this plugin**.

However, the `animated` elements from `@react-spring/three`, like `<animated.mesh />`, WILL be picked up by this plugin.

But something like this will not:

```jsx
const StyledMesh = styled('mesh')

<StyledMesh />
```js
// .babelrc or babel.config.js
{
plugins: ['@react-three/babel']
}
```
5 changes: 0 additions & 5 deletions example/.gitignore

This file was deleted.

13 changes: 0 additions & 13 deletions example/index.html

This file was deleted.

22 changes: 0 additions & 22 deletions example/package.json

This file was deleted.

6 changes: 0 additions & 6 deletions example/src/favicon.svg

This file was deleted.

16 changes: 0 additions & 16 deletions example/src/index.css

This file was deleted.

Loading

0 comments on commit be04652

Please sign in to comment.