Skip to content

Commit 860c97c

Browse files
authored
SWC import modularization plugin (#34969)
1 parent 78831c3 commit 860c97c

File tree

22 files changed

+653
-6
lines changed

22 files changed

+653
-6
lines changed

docs/advanced-features/compiler.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,89 @@ module.exports = {
233233

234234
If you have feedback about `swcMinify`, please share it on the [feedback discussion](https://github.com/vercel/next.js/discussions/30237).
235235

236+
### Modularize Imports
237+
238+
Allows to modularize imports, similar to [babel-plugin-transform-imports](https://www.npmjs.com/package/babel-plugin-transform-imports).
239+
240+
Transforms member style imports:
241+
242+
```js
243+
import { Row, Grid as MyGrid } from 'react-bootstrap'
244+
import { merge } from 'lodash'
245+
```
246+
247+
...into default style imports:
248+
249+
```js
250+
import Row from 'react-bootstrap/lib/Row'
251+
import MyGrid from 'react-bootstrap/lib/Grid'
252+
import merge from 'lodash/merge'
253+
```
254+
255+
Config for the above transform:
256+
257+
```js
258+
// next.config.js
259+
module.exports = {
260+
experimental: {
261+
modularizeImports: {
262+
'react-bootstrap': {
263+
transform: 'react-bootstrap/lib/{{member}}',
264+
},
265+
lodash: {
266+
transform: 'lodash/{{member}}',
267+
},
268+
},
269+
},
270+
}
271+
```
272+
273+
Advanced transformations:
274+
275+
- Using regular expressions
276+
277+
Similar to `babel-plugin-transform-imports`, but the transform is templated with [handlebars](https://docs.rs/handlebars) and regular expressions are in Rust [regex](https://docs.rs/regex/latest/regex/) crate's syntax.
278+
279+
The config:
280+
281+
```js
282+
// next.config.js
283+
module.exports = {
284+
experimental: {
285+
modularizeImports: {
286+
'my-library/?(((\\w*)?/?)*)': {
287+
transform: 'my-library/{{ matches.[1] }}/{{member}}',
288+
},
289+
},
290+
},
291+
}
292+
```
293+
294+
Cause this code:
295+
296+
```js
297+
import { MyModule } from 'my-library'
298+
import { App } from 'my-library/components'
299+
import { Header, Footer } from 'my-library/components/App'
300+
```
301+
302+
To become:
303+
304+
```js
305+
import MyModule from 'my-library/MyModule'
306+
import App from 'my-library/components/App'
307+
import Header from 'my-library/components/App/Header'
308+
import Footer from 'my-library/components/App/Footer'
309+
```
310+
311+
- Handlebars templating
312+
313+
This transform uses [handlebars](https://docs.rs/handlebars) to template the replacement import path in the `transform` field. These variables and helper functions are available:
314+
315+
1. `matches`: Has type `string[]`. All groups matched by the regular expression. `matches.[0]` is the full match.
316+
2. `member`: Has type `string`. The name of the member import.
317+
3. `lowerCase`, `upperCase`, `camelCase`: Helper functions to convert a string to lower, upper or camel cases.
318+
236319
## Unsupported Features
237320

238321
When your application has a `.babelrc` file, Next.js will automatically fall back to using Babel for transforming individual files. This ensures backwards compatibility with existing applications that leverage custom Babel plugins.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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+
# next.js
12+
/.next/
13+
/out/
14+
15+
# production
16+
/build
17+
18+
# misc
19+
.DS_Store
20+
*.pem
21+
22+
# debug
23+
npm-debug.log*
24+
yarn-debug.log*
25+
yarn-error.log*
26+
27+
# local env files
28+
.env.local
29+
.env.development.local
30+
.env.test.local
31+
.env.production.local
32+
33+
# vercel
34+
.vercel
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Modularize Imports Example
2+
3+
This example shows how to use the `modularizeImports` config option.
4+
5+
## Preview
6+
7+
Preview the example live on [StackBlitz](http://stackblitz.com/):
8+
9+
[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/vercel/next.js/tree/canary/examples/modularize-imports)
10+
11+
## Deploy your own
12+
13+
Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example):
14+
15+
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/modularize-imports&project-name=modularize-imports&repository-name=modularize-imports)
16+
17+
## How to use
18+
19+
Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:
20+
21+
```bash
22+
npx create-next-app --example modularize-imports modularize-imports-app
23+
# or
24+
yarn create next-app --example modularize-imports modularize-imports-app
25+
```
26+
27+
Deploy it to the cloud with [Vercel](https://vercel.com/new?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function LeftHalf() {
2+
return <span>Modularize</span>
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function RightHalf() {
2+
return <span>Imports</span>
3+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// import LeftHalf from './LeftHalf'
2+
// import RightHalf from './RightHalf'
3+
4+
// Remove the exports here so that we can verify that `modularize-imports` is working.
5+
// export { LeftHalf, RightHalf };
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module.exports = {
2+
experimental: {
3+
modularizeImports: {
4+
'../components/halves': {
5+
transform: '../components/halves/{{ member }}',
6+
},
7+
},
8+
},
9+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"private": true,
3+
"scripts": {
4+
"dev": "next dev",
5+
"build": "next build",
6+
"start": "next start"
7+
},
8+
"dependencies": {
9+
"next": "latest",
10+
"react": "^17.0.2",
11+
"react-dom": "^17.0.2"
12+
}
13+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { LeftHalf, RightHalf } from '../components/halves'
2+
3+
const Index = () => (
4+
<div>
5+
<LeftHalf />
6+
<RightHalf />
7+
</div>
8+
)
9+
10+
export default Index

0 commit comments

Comments
 (0)