Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 34 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ app.prepare().then(() => {
```

The `next` API is as follows:
- `next(path: string, opts: object)` - `path` is
- `next(path: string, opts: object)` - `path` is
- `next(opts: object)`

Supported options:
Expand Down Expand Up @@ -396,10 +396,40 @@ In order to extend our usage of `webpack`, you can define a function that extend
The following example shows how you can use [`react-svg-loader`](https://github.com/boopathi/react-svg-loader) to easily import any `.svg` file as a React component, without modification.

```js
// This file is not going through babel transformation.
// So, we write it in vanilla JS
// (But you could use ES2015 features supported by your Node.js version)

module.exports = {
webpack: (config, { dev }) => {
config.module.rules.push({ test: /\.svg$/, loader: 'babel!react-svg' })

// Important: return the modified config
return config
}
}
```

### Customizing babel config

In order to extend our usage of `babel`, you can define a function that extends its config via `next.config.js`.

The following example config shows you how to use `babel-preset-stage-0` with your app.

```js
// This file is not going through babel transformation.
// So, we write it in vanilla JS
// (But you could use ES2015 features supported by your Node.js version)

module.exports = {
webpack: (cfg, { dev }) => {
cfg.module.rules.push({ test: /\.svg$/, loader: 'babel!react-svg' })
return cfg
// config is the set of options we pass to our babel-loaders's query option
babel: function (config, { dev }) {
// Add the stage-0 preset.
// Make sure to use 'require.resolve' otherwise we won't be able to find it.
config.presets.push(require.resolve('babel-preset-stage-0'))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems a bit too hacky to recommend. I wonder if the following works.

import presetStage0 from 'babel-preset-stage0'

...

config.presets.push(presetStage0)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't import since it's next.config.js. It didn't work for me for simply giving the preset.

I will try more options.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a pretty good option. I like it.
I thought we wanted to expose everything via next.config.js.

@rauchg what do you think?


// Important: return the modified config
return config
}
}
```
Expand Down
13 changes: 13 additions & 0 deletions examples/with-custom-babel-config/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Example app using custom babel config

This example features:

* An app using proposed [do expressions](https://babeljs.io/docs/plugins/transform-do-expressions/).
* It uses babel-preset-stage-0, which allows us to use above JavaScript feature.

## How to run it

```sh
npm install
npm run dev
```
15 changes: 15 additions & 0 deletions examples/with-custom-babel-config/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// This file is not going through babel transformation.
// So, we write it in vanilla JS
// (But you could use ES2015 features supported by your Node.js version)

module.exports = {
// config is the set of options we pass to our babel-loaders's query option
babel: function (config) {
// Add the stage-0 preset.
// Make sure to use 'require.resolve' otherwise we won't be able to find it.
config.presets.push(require.resolve('babel-preset-stage-0'))

// Important: return the modified config
return config
}
}
19 changes: 19 additions & 0 deletions examples/with-custom-babel-config/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "with-custom-babel-config",
"version": "1.0.0",
"description": "This example features:",
"main": "index.js",
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start"
},
"dependencies": {
"next": "^2.0.0-beta"
},
"author": "",
"license": "ISC",
"devDependencies": {
"babel-preset-stage-0": "^6.16.0"
}
}
46 changes: 46 additions & 0 deletions examples/with-custom-babel-config/pages/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React from 'react'

export default class MyLuckNo extends React.Component {
constructor (...args) {
super(...args)
this.state = { randomNo: null }
}

componentDidMount () {
this.recalculate()
}

recalculate () {
this.setState({
randomNo: Math.ceil(Math.random() * 100)
})
}

render () {
const { randomNo } = this.state

if (randomNo === null) {
return (<p>Please wait..</p>)
}

// This is an experimental JavaScript feature where we can get with
// using babel-preset-stage-0
const message = do {
if (randomNo < 30) {
'Do not give up. Try again.'
} else if (randomNo < 60) {
'You are a lucky guy'
} else {
'You are soooo lucky!'
}
}

return (
<div>
<h3>Your Lucky number is: "{randomNo}"</h3>
<p>{message}</p>
<button onClick={() => this.recalculate()}>Try Again</button>
</div>
)
}
}
13 changes: 11 additions & 2 deletions server/build/babel/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ import { readFile, writeFile } from 'mz/fs'
import { transform } from 'babel-core'
import chokidar from 'chokidar'
import mkdirp from 'mkdirp-then'
import getConfig from '../../config'

export default babel

async function babel (dir, { dev = false } = {}) {
dir = resolve(dir)
const config = getConfig('../')

let src
try {
Expand All @@ -20,11 +22,18 @@ async function babel (dir, { dev = false } = {}) {
}
}

const { code } = transform(src, {
let babelOptions = {
babelrc: false,
sourceMaps: dev ? 'inline' : false,
presets: [require.resolve('./preset')]
})
}

if (config.babel) {
console.log('> Using "babel" config function defined in next.config.js.')
babelOptions = await config.babel(babelOptions, { dev })
}

const { code } = transform(src, babelOptions)

const file = join(dir, '.next', 'dist', 'pages', '_document.js')
await mkdirp(dirname(file))
Expand Down
26 changes: 17 additions & 9 deletions server/build/webpack.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import getConfig from '../config'

export default async function createCompiler (dir, { dev = false, quiet = false } = {}) {
dir = resolve(dir)
const config = getConfig(dir)

const pages = await glob('pages/**/*.js', {
cwd: dir,
Expand Down Expand Up @@ -83,6 +84,19 @@ export default async function createCompiler (dir, { dev = false, quiet = false
)
}

let mainBabelOptions = {
babelrc: false,
sourceMaps: dev ? 'both' : false,
presets: [
require.resolve('./babel/preset')
]
}

if (config.babel) {
console.log('> Using "babel" config function defined in next.config.js.')
mainBabelOptions = await config.babel(mainBabelOptions, { dev })
}

const loaders = (dev ? [{
test: /\.js(\?[^?]*)?$/,
loader: 'hot-self-accept-loader',
Expand Down Expand Up @@ -133,13 +147,7 @@ export default async function createCompiler (dir, { dev = false, quiet = false
exclude (str) {
return /node_modules/.test(str) && str.indexOf(nextPagesDir) !== 0
},
query: {
babelrc: false,
sourceMaps: dev ? 'both' : false,
presets: [
require.resolve('./babel/preset')
]
}
query: mainBabelOptions
}])

const interpolateNames = new Map([
Expand Down Expand Up @@ -188,9 +196,9 @@ export default async function createCompiler (dir, { dev = false, quiet = false
return interpolateNames.get(this.resourcePath) || url
}
}
const config = getConfig(dir)

if (config.webpack) {
console.log('> Using Webpack config function defined in next.config.js.')
console.log('> Using "webpack" config function defined in next.config.js.')
webpackConfig = await config.webpack(webpackConfig, { dev })
}
return webpack(webpackConfig)
Expand Down