UNPKG

6.19 kBMarkdownView Raw
1# Next.js + Transpile `node_modules`
2
3[![Build Status](https://img.shields.io/circleci/project/github/martpie/next-transpile-modules.svg)](https://circleci.com/gh/martpie/next-transpile-modules)
4![Dependencies](https://img.shields.io/david/martpie/next-transpile-modules)
5
6Transpile untranspiled modules from `node_modules` using the Next.js Babel configuration.
7Makes it easy to have local libraries and keep a slick, manageable dev experience.
8
9## What problems does it solve?
10
11This plugin aims to solve the following challenges:
12
13- code transpilation from local packages (think: a monorepo with a `styleguide` package)
14- code transpilation from NPM modules using ES6 imports (e.g `lodash-es`)
15
16What this plugin **does not aim** to solve:
17
18- any-package IE11-compatible maker
19
20## Compatibility table
21
22| Next.js version | Plugin version |
23| --------------- | -------------- |
24| Next.js 9.2+ | 3.x |
25| Next.js 8 / 9 | 2.x |
26| Next.js 6 / 7 | 1.x |
27
28## Installation
29
30```
31npm install --save next-transpile-modules
32```
33
34or
35
36```
37yarn add next-transpile-modules
38```
39
40## Usage
41
42### Classic:
43
44```js
45// next.config.js
46const withTM = require('next-transpile-modules')(['somemodule', 'and-another']); // pass the modules you would like to see transpiled
47
48module.exports = withTM();
49```
50
51**note:** please declare `withTM` as your last plugin (the "most nested" one).
52
53### Scoped packages
54
55You can include scoped packages or nested ones:
56
57```js
58const withTM = require('next-transpile-modules')(['@shared/ui', '@shared/utils']);
59
60// ...
61```
62
63```js
64const withTM = require('next-transpile-modules')(['styleguide/components']);
65
66// ...
67```
68
69### With `next-compose-plugins`:
70
71```js
72const withPlugins = require('next-compose-plugins');
73const withTM = require('next-transpile-modules')(['some-module', 'and-another']);
74
75module.exports = withPlugins([withTM], {
76 // ...
77});
78```
79
80### CSS support
81
82Since `next-transpile-modules@3` and `next@>9.2`, this plugin will also transpile CSS included in your transpiled packages:
83
84In your transpiled package:
85
86```js
87// shared-ui/components/Button.js
88import styles from './Button.module.css';
89
90function Button(props) {
91 return (
92 <button type='button' className={styles.error}>
93 {props.children}
94 </button>
95 );
96}
97
98export default Button;
99```
100
101```css
102/* shared-ui/components/Button.module.js */
103.error {
104 color: white;
105 background-color: red;
106}
107```
108
109In your app:
110
111```js
112// next.config.js
113const withTM = require('next-transpile-modules')(['shared-ui']);
114
115// ...
116```
117
118```jsx
119// pages/home.jsx
120import React from 'react';
121import Button from 'shared-ui/components/Button';
122
123const HomePage = () => {
124 return (
125 <main>
126 {/* will output <button class="Button_error__xxxxx"> */}
127 <Button>Styled button</Button>
128 </main>
129 );
130};
131
132export default HomePage;
133```
134
135It also supports global CSS import packages located in `node_modules`:
136
137```jsx
138// pages/_app.js
139import 'shared-ui/styles/global.css'; // will be imported globally
140
141export default function MyApp({ Component, pageProps }) {
142 return <Component {...pageProps} />;
143}
144```
145
146## FAQ
147
148### What is the difference with `@weco/next-plugin-transpile-modules`?
149
150- it is maintained, `@weco`'s seems dead
151- it supports TypeScript
152- it supports CSS modules (since Next.js 9.2)
153
154### I have trouble making it work with Next.js 7
155
156Next.js 7 introduced Webpack 4 and Babel 7, [which changed a couple of things](https://github.com/zeit/next.js/issues/5393#issuecomment-458517433), especially for TypeScript and Flow plugins.
157
158If you have a transpilation error when loading a page, check that your `babel.config.js` is up to date and valid, [you may have forgotten a preset](https://github.com/martpie/next-transpile-modules/issues/1#issuecomment-427749256) there.
159
160### I have trouble with transpilation and Flow/TypeScript
161
162In your Next.js app, make sure you use a `babel.config.js` and not a `.babelrc` as Babel's configuration file (see explanation below).
163
164**Since Next.js 9, you probably don't need that file anymore**, as TypeScript is supported natively.
165
166### I have trouble with transpilation and Yarn workspaces
167
168If you get a transpilation error when using Yarn workspaces, make sure you are using a `babel.config.js` and not a `.babelrc`. The former is [a project-wide Babel configuration](https://babeljs.io/docs/en/config-files), when the latter works for relative paths only (and won't work as Yarn install dependencies in a parent directory).
169
170### I have trouble with Yarn and hot reloading
171
172If you add a local library (let's say with `yarn add ../some-shared-module`), Yarn will copy those files by default, instead of symlinking them. So your changes to the initial folder won't be copied to your Next.js `node_modules` directory.
173
174You can go back to `npm`, or use Yarn workspaces. See [an example](https://github.com/zeit/next.js/tree/canary/examples/with-yarn-workspaces) in the official Next.js repo.
175
176### I have trouble making it work with Lerna
177
178Lerna's purpose is to publish different packages from a monorepo, **it does not help for and does not intend to help local development with local modules**.
179
180This is not coming from me, but [from Lerna's maintainer](https://github.com/lerna/lerna/issues/1243#issuecomment-401396850).
181
182So you are probably [using it wrong](https://github.com/martpie/next-transpile-modules/issues/5#issuecomment-441501107), and I advice you to use `npm` or Yarn workspaces instead.
183
184### But... I really need to make it work with Lerna!
185
186You may need to tell your Webpack configuration how to properly resolve your scoped packages, as they won't be installed in your Next.js directory, but the root of your Lerna setup.
187
188```js
189const withTM = require('next-transpile-modules')(['@your-project/shared', '@your-project/styleguide']);
190
191module.exports = withTM({
192 webpack: (config, options) => {
193 config.resolve.alias = {
194 ...config.resolve.alias,
195 // Will make webpack look for these modules in parent directories
196 '@your-project/shared': require.resolve('@your-project/shared'),
197 '@your-project/styleguide': require.resolve('@your-project/styleguide')
198 // ...
199 };
200 return config;
201 }
202});
203```