mirror of
https://github.com/terribleplan/next.js.git
synced 2024-01-19 02:48:18 +00:00
Add core import() support.
This commit is contained in:
parent
6f735eeb05
commit
f51300f14b
27
examples/with-dynamic-import/README.md
Normal file
27
examples/with-dynamic-import/README.md
Normal file
|
@ -0,0 +1,27 @@
|
|||
# Example app with dynamic-imports
|
||||
|
||||
## How to use
|
||||
|
||||
Download the example [or clone the repo](https://github.com/zeit/next.js):
|
||||
|
||||
```bash
|
||||
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/shared-modules
|
||||
cd shared-modules
|
||||
```
|
||||
|
||||
Install it and run:
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download))
|
||||
|
||||
```bash
|
||||
now
|
||||
```
|
||||
|
||||
## The idea behind the example
|
||||
|
||||
This examples shows how to dynamically import modules via [`import()`](https://github.com/tc39/proposal-dynamic-import) API
|
19
examples/with-dynamic-import/components/Counter.js
Normal file
19
examples/with-dynamic-import/components/Counter.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
import React from 'react'
|
||||
|
||||
let count = 0
|
||||
|
||||
export default class Counter extends React.Component {
|
||||
add () {
|
||||
count += 1
|
||||
this.forceUpdate()
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div>
|
||||
<p>Count is: {count}</p>
|
||||
<button onClick={() => this.add()}>Add</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
19
examples/with-dynamic-import/components/Header.js
Normal file
19
examples/with-dynamic-import/components/Header.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
import Link from 'next/link'
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<Link href='/'>
|
||||
<a style={styles.a} >Home</a>
|
||||
</Link>
|
||||
|
||||
<Link href='/about'>
|
||||
<a style={styles.a} >About</a>
|
||||
</Link>
|
||||
</div>
|
||||
)
|
||||
|
||||
const styles = {
|
||||
a: {
|
||||
marginRight: 10
|
||||
}
|
||||
}
|
3
examples/with-dynamic-import/components/hello.js
Normal file
3
examples/with-dynamic-import/components/hello.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
export default () => (
|
||||
<p>Hello World (imported dynamiclly) </p>
|
||||
)
|
23
examples/with-dynamic-import/lib/with-import.js
Normal file
23
examples/with-dynamic-import/lib/with-import.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
import React from 'react'
|
||||
|
||||
export default function withImport (promise, Loading = () => (<p>Loading...</p>)) {
|
||||
return class Comp extends React.Component {
|
||||
constructor (...args) {
|
||||
super(...args)
|
||||
this.state = { AsyncComponent: null }
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
promise.then((AsyncComponent) => {
|
||||
this.setState({ AsyncComponent })
|
||||
})
|
||||
}
|
||||
|
||||
render () {
|
||||
const { AsyncComponent } = this.state
|
||||
if (!AsyncComponent) return (<Loading {...this.props} />)
|
||||
|
||||
return <AsyncComponent {...this.props} />
|
||||
}
|
||||
}
|
||||
}
|
18
examples/with-dynamic-import/package.json
Normal file
18
examples/with-dynamic-import/package.json
Normal file
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "with-dynamic-import",
|
||||
"version": "1.0.0",
|
||||
"description": "This example features:",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"dev": "next",
|
||||
"build": "next build",
|
||||
"start": "next start"
|
||||
},
|
||||
"dependencies": {
|
||||
"next": "*",
|
||||
"react": "^15.4.2",
|
||||
"react-dom": "^15.4.2"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
12
examples/with-dynamic-import/pages/about.js
Normal file
12
examples/with-dynamic-import/pages/about.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
import Header from '../components/Header'
|
||||
import Counter from '../components/Counter'
|
||||
|
||||
const About = () => (
|
||||
<div>
|
||||
<Header />
|
||||
<p>This is the about page.</p>
|
||||
<Counter />
|
||||
</div>
|
||||
)
|
||||
|
||||
export default About
|
15
examples/with-dynamic-import/pages/index.js
Normal file
15
examples/with-dynamic-import/pages/index.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
import React from 'react'
|
||||
import Header from '../components/Header'
|
||||
import Counter from '../components/Counter'
|
||||
import withImport from '../lib/with-import'
|
||||
|
||||
const DynamicComponent = withImport(import('../components/hello'))
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<Header />
|
||||
<DynamicComponent />
|
||||
<p>HOME PAGE is here!</p>
|
||||
<Counter />
|
||||
</div>
|
||||
)
|
|
@ -52,6 +52,7 @@
|
|||
"babel-loader": "6.4.1",
|
||||
"babel-plugin-module-resolver": "2.6.2",
|
||||
"babel-plugin-react-require": "3.0.0",
|
||||
"babel-plugin-syntax-dynamic-import": "6.18.0",
|
||||
"babel-plugin-transform-class-properties": "6.22.0",
|
||||
"babel-plugin-transform-es2015-modules-commonjs": "6.24.0",
|
||||
"babel-plugin-transform-object-rest-spread": "6.22.0",
|
||||
|
@ -61,6 +62,7 @@
|
|||
"babel-preset-latest": "6.24.0",
|
||||
"babel-preset-react": "6.23.0",
|
||||
"babel-runtime": "6.23.0",
|
||||
"babel-template": "6.24.1",
|
||||
"case-sensitive-paths-webpack-plugin": "2.0.0",
|
||||
"cross-spawn": "5.1.0",
|
||||
"del": "2.2.2",
|
||||
|
|
41
server/build/babel/plugins/handle-import.js
Normal file
41
server/build/babel/plugins/handle-import.js
Normal file
|
@ -0,0 +1,41 @@
|
|||
// Based on https://github.com/airbnb/babel-plugin-dynamic-import-webpack
|
||||
// We've added support for SSR with this version
|
||||
import template from 'babel-template'
|
||||
import syntax from 'babel-plugin-syntax-dynamic-import'
|
||||
import UUID from 'uuid'
|
||||
|
||||
const TYPE_IMPORT = 'Import'
|
||||
|
||||
const buildImport = (args) => (template(`
|
||||
(
|
||||
new Promise((resolve) => {
|
||||
if (process.pid) {
|
||||
eval('require.ensure = (deps, callback) => (callback(require))')
|
||||
}
|
||||
|
||||
require.ensure([], (require) => {
|
||||
let m = require(SOURCE)
|
||||
m = m.default || m
|
||||
m.__webpackChunkName = '${args.name}.js'
|
||||
resolve(m);
|
||||
}, 'chunks/${args.name}.js');
|
||||
})
|
||||
)
|
||||
`))
|
||||
|
||||
export default () => ({
|
||||
inherits: syntax,
|
||||
|
||||
visitor: {
|
||||
CallExpression (path) {
|
||||
if (path.node.callee.type === TYPE_IMPORT) {
|
||||
const newImport = buildImport({
|
||||
name: UUID.v4()
|
||||
})({
|
||||
SOURCE: path.node.arguments
|
||||
})
|
||||
path.replaceWith(newImport)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
|
@ -20,6 +20,7 @@ module.exports = {
|
|||
],
|
||||
plugins: [
|
||||
require.resolve('babel-plugin-react-require'),
|
||||
require.resolve('./plugins/handle-import'),
|
||||
require.resolve('babel-plugin-transform-object-rest-spread'),
|
||||
require.resolve('babel-plugin-transform-class-properties'),
|
||||
require.resolve('babel-plugin-transform-runtime'),
|
||||
|
|
|
@ -277,7 +277,9 @@ export default async function createCompiler (dir, { dev = false, quiet = false,
|
|||
|
||||
// append hash id for cache busting
|
||||
return `webpack:///${resourcePath}?${id}`
|
||||
}
|
||||
},
|
||||
// This saves chunks with the name given via require.ensure()
|
||||
chunkFilename: '[name]'
|
||||
},
|
||||
resolve: {
|
||||
modules: [
|
||||
|
|
|
@ -91,6 +91,13 @@ export default class Server {
|
|||
await this.serveStatic(req, res, p)
|
||||
},
|
||||
|
||||
// This is to support, webpack dynamic imports in production.
|
||||
'/_webpack/chunks/:name': async (req, res, params) => {
|
||||
res.setHeader('Cache-Control', 'max-age=365000000, immutable')
|
||||
const p = join(this.dir, '.next', 'chunks', params.name)
|
||||
await this.serveStatic(req, res, p)
|
||||
},
|
||||
|
||||
'/_next/:hash/manifest.js': async (req, res, params) => {
|
||||
this.handleBuildHash('manifest.js', params.hash, res)
|
||||
const p = join(this.dir, `${this.dist}/manifest.js`)
|
||||
|
|
41
yarn.lock
41
yarn.lock
|
@ -504,6 +504,10 @@ babel-plugin-syntax-class-properties@^6.8.0:
|
|||
version "6.13.0"
|
||||
resolved "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de"
|
||||
|
||||
babel-plugin-syntax-dynamic-import@^6.18.0:
|
||||
version "6.18.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da"
|
||||
|
||||
babel-plugin-syntax-exponentiation-operator@^6.8.0:
|
||||
version "6.13.0"
|
||||
resolved "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de"
|
||||
|
@ -894,6 +898,16 @@ babel-template@^6.16.0, babel-template@^6.22.0, babel-template@^6.23.0, babel-te
|
|||
babylon "^6.11.0"
|
||||
lodash "^4.2.0"
|
||||
|
||||
babel-template@^6.24.1:
|
||||
version "6.24.1"
|
||||
resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.24.1.tgz#04ae514f1f93b3a2537f2a0f60a5a45fb8308333"
|
||||
dependencies:
|
||||
babel-runtime "^6.22.0"
|
||||
babel-traverse "^6.24.1"
|
||||
babel-types "^6.24.1"
|
||||
babylon "^6.11.0"
|
||||
lodash "^4.2.0"
|
||||
|
||||
babel-traverse@6.21.0:
|
||||
version "6.21.0"
|
||||
resolved "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.21.0.tgz#69c6365804f1a4f69eb1213f85b00a818b8c21ad"
|
||||
|
@ -922,6 +936,20 @@ babel-traverse@^6.18.0, babel-traverse@^6.22.0, babel-traverse@^6.23.0, babel-tr
|
|||
invariant "^2.2.0"
|
||||
lodash "^4.2.0"
|
||||
|
||||
babel-traverse@^6.24.1:
|
||||
version "6.24.1"
|
||||
resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.24.1.tgz#ab36673fd356f9a0948659e7b338d5feadb31695"
|
||||
dependencies:
|
||||
babel-code-frame "^6.22.0"
|
||||
babel-messages "^6.23.0"
|
||||
babel-runtime "^6.22.0"
|
||||
babel-types "^6.24.1"
|
||||
babylon "^6.15.0"
|
||||
debug "^2.2.0"
|
||||
globals "^9.0.0"
|
||||
invariant "^2.2.0"
|
||||
lodash "^4.2.0"
|
||||
|
||||
babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.21.0, babel-types@^6.22.0, babel-types@^6.23.0:
|
||||
version "6.23.0"
|
||||
resolved "https://registry.npmjs.org/babel-types/-/babel-types-6.23.0.tgz#bb17179d7538bad38cd0c9e115d340f77e7e9acf"
|
||||
|
@ -931,6 +959,15 @@ babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.21.0, babel-types@^6.22
|
|||
lodash "^4.2.0"
|
||||
to-fast-properties "^1.0.1"
|
||||
|
||||
babel-types@^6.24.1:
|
||||
version "6.24.1"
|
||||
resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.24.1.tgz#a136879dc15b3606bda0d90c1fc74304c2ff0975"
|
||||
dependencies:
|
||||
babel-runtime "^6.22.0"
|
||||
esutils "^2.0.2"
|
||||
lodash "^4.2.0"
|
||||
to-fast-properties "^1.0.1"
|
||||
|
||||
babylon@6.14.1, babylon@^6.11.0:
|
||||
version "6.14.1"
|
||||
resolved "https://registry.npmjs.org/babylon/-/babylon-6.14.1.tgz#956275fab72753ad9b3435d7afe58f8bf0a29815"
|
||||
|
@ -4023,11 +4060,11 @@ public-encrypt@^4.0.0:
|
|||
parse-asn1 "^5.0.0"
|
||||
randombytes "^2.0.1"
|
||||
|
||||
punycode@1.3.2:
|
||||
punycode@1.3.2, punycode@^1.2.4:
|
||||
version "1.3.2"
|
||||
resolved "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d"
|
||||
|
||||
punycode@^1.2.4, punycode@^1.4.1:
|
||||
punycode@^1.4.1:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
|
||||
|
||||
|
|
Loading…
Reference in a new issue