mirror of
https://github.com/terribleplan/next.js.git
synced 2024-01-19 02:48:18 +00:00
Bundle all the modules inside the app (#414)
* Remove the use of CDN and bundle everything inside the app. We still pre-build the prefetcher because it needs different webpack config which only targets browsers supports Service Workers. * Remove cdn config item. We no longer using it. * Stop adding script tags when staticMarkup=true * Remove babel-plugin-transform-remove-strict-mode NPM module.
This commit is contained in:
parent
59d514e071
commit
b62a0e8f55
|
@ -1,6 +1,4 @@
|
||||||
import 'react-hot-loader/patch'
|
import 'react-hot-loader/patch'
|
||||||
import * as next from './next'
|
import * as next from './next'
|
||||||
import { requireModule } from '../lib/eval-script'
|
|
||||||
|
|
||||||
window.next = next
|
window.next = next
|
||||||
module.exports = requireModule
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import domready from 'domready'
|
||||||
import { rehydrate } from '../lib/css'
|
import { rehydrate } from '../lib/css'
|
||||||
import Router from '../lib/router'
|
import Router from '../lib/router'
|
||||||
import App from '../lib/app'
|
import App from '../lib/app'
|
||||||
import evalScript, { requireModule } from '../lib/eval-script'
|
import evalScript from '../lib/eval-script'
|
||||||
|
|
||||||
const {
|
const {
|
||||||
__NEXT_DATA__: {
|
__NEXT_DATA__: {
|
||||||
|
@ -41,5 +41,3 @@ domready(() => {
|
||||||
if (ids) rehydrate(ids)
|
if (ids) rehydrate(ids)
|
||||||
render(createElement(App, appProps), container)
|
render(createElement(App, appProps), container)
|
||||||
})
|
})
|
||||||
|
|
||||||
module.exports = requireModule
|
|
||||||
|
|
|
@ -12,8 +12,5 @@
|
||||||
"next": "*"
|
"next": "*"
|
||||||
},
|
},
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC"
|
||||||
"next": {
|
|
||||||
"cdn": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
62
gulpfile.js
62
gulpfile.js
|
@ -71,69 +71,9 @@ gulp.task('copy-bench-fixtures', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
gulp.task('build', [
|
gulp.task('build', [
|
||||||
'build-dev-client',
|
|
||||||
'build-client',
|
|
||||||
'build-prefetcher'
|
'build-prefetcher'
|
||||||
])
|
])
|
||||||
|
|
||||||
gulp.task('build-dev-client', ['compile-lib', 'compile-client'], () => {
|
|
||||||
return gulp
|
|
||||||
.src('dist/client/next-dev.js')
|
|
||||||
.pipe(webpack({
|
|
||||||
quiet: true,
|
|
||||||
output: { filename: 'next-dev.bundle.js', libraryTarget: 'var', library: 'require' },
|
|
||||||
module: {
|
|
||||||
loaders: [
|
|
||||||
{
|
|
||||||
test: /eval-script\.js$/,
|
|
||||||
exclude: /node_modules/,
|
|
||||||
loader: 'babel',
|
|
||||||
query: {
|
|
||||||
plugins: [
|
|
||||||
'babel-plugin-transform-remove-strict-mode'
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
.pipe(gulp.dest('dist/client'))
|
|
||||||
.pipe(notify('Built dev client'))
|
|
||||||
})
|
|
||||||
|
|
||||||
gulp.task('build-client', ['compile-lib', 'compile-client'], () => {
|
|
||||||
return gulp
|
|
||||||
.src('dist/client/next.js')
|
|
||||||
.pipe(webpack({
|
|
||||||
quiet: true,
|
|
||||||
output: { filename: 'next.bundle.js', libraryTarget: 'var', library: 'require' },
|
|
||||||
plugins: [
|
|
||||||
new webpack.webpack.DefinePlugin({
|
|
||||||
'process.env': {
|
|
||||||
NODE_ENV: JSON.stringify('production')
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
new webpack.webpack.optimize.UglifyJsPlugin()
|
|
||||||
],
|
|
||||||
module: {
|
|
||||||
loaders: [
|
|
||||||
{
|
|
||||||
test: /eval-script\.js$/,
|
|
||||||
exclude: /node_modules/,
|
|
||||||
loader: 'babel',
|
|
||||||
query: {
|
|
||||||
plugins: [
|
|
||||||
'babel-plugin-transform-remove-strict-mode'
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
.pipe(gulp.dest('dist/client'))
|
|
||||||
.pipe(notify('Built release client'))
|
|
||||||
})
|
|
||||||
|
|
||||||
gulp.task('build-prefetcher', ['compile-lib', 'compile-client'], () => {
|
gulp.task('build-prefetcher', ['compile-lib', 'compile-client'], () => {
|
||||||
return gulp
|
return gulp
|
||||||
.src('client/next-prefetcher.js')
|
.src('client/next-prefetcher.js')
|
||||||
|
@ -172,7 +112,7 @@ gulp.task('build-prefetcher', ['compile-lib', 'compile-client'], () => {
|
||||||
.pipe(notify('Built release prefetcher'))
|
.pipe(notify('Built release prefetcher'))
|
||||||
})
|
})
|
||||||
|
|
||||||
gulp.task('test', () => {
|
gulp.task('test', ['compile'], () => {
|
||||||
return gulp.src('./test')
|
return gulp.src('./test')
|
||||||
.pipe(jest.default({
|
.pipe(jest.default({
|
||||||
coverage: true,
|
coverage: true,
|
||||||
|
|
|
@ -1,32 +1,3 @@
|
||||||
import React from 'react'
|
|
||||||
import ReactDOM from 'react-dom'
|
|
||||||
import App from '../lib/app'
|
|
||||||
import Link from '../lib/link'
|
|
||||||
import * as Prefetch from '../lib/prefetch'
|
|
||||||
import * as Css from '../lib/css'
|
|
||||||
import Head from '../lib/head'
|
|
||||||
|
|
||||||
const modules = new Map([
|
|
||||||
['react', React],
|
|
||||||
['react-dom', ReactDOM],
|
|
||||||
['next/app', App],
|
|
||||||
['next/link', Link],
|
|
||||||
['next/prefetch', Prefetch],
|
|
||||||
['next/css', Css],
|
|
||||||
['next/head', Head]
|
|
||||||
])
|
|
||||||
|
|
||||||
function require (moduleName) {
|
|
||||||
const name = moduleName
|
|
||||||
const m = modules.get(name)
|
|
||||||
|
|
||||||
if (m) return m
|
|
||||||
|
|
||||||
throw new Error(`Module "${moduleName}" is not exists in the bundle`)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const requireModule = require
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IMPORTANT: This module is compiled *without* `use strict`
|
* IMPORTANT: This module is compiled *without* `use strict`
|
||||||
* so that when we `eval` a dependency below, we don't enforce
|
* so that when we `eval` a dependency below, we don't enforce
|
||||||
|
@ -41,6 +12,7 @@ export const requireModule = require
|
||||||
|
|
||||||
export default function evalScript (script) {
|
export default function evalScript (script) {
|
||||||
const module = { exports: {} }
|
const module = { exports: {} }
|
||||||
|
|
||||||
eval(script) // eslint-disable-line no-eval
|
eval(script) // eslint-disable-line no-eval
|
||||||
return module.exports
|
return module.exports
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,6 @@
|
||||||
"react": "15.4.1",
|
"react": "15.4.1",
|
||||||
"react-dom": "15.4.1",
|
"react-dom": "15.4.1",
|
||||||
"react-hot-loader": "3.0.0-beta.6",
|
"react-hot-loader": "3.0.0-beta.6",
|
||||||
"read-pkg-up": "2.0.0",
|
|
||||||
"send": "0.14.1",
|
"send": "0.14.1",
|
||||||
"source-map-support": "0.4.6",
|
"source-map-support": "0.4.6",
|
||||||
"strip-ansi": "3.0.1",
|
"strip-ansi": "3.0.1",
|
||||||
|
@ -75,7 +74,6 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-eslint": "7.1.1",
|
"babel-eslint": "7.1.1",
|
||||||
"babel-plugin-transform-remove-strict-mode": "0.0.2",
|
|
||||||
"babel-preset-env": "1.0.2",
|
"babel-preset-env": "1.0.2",
|
||||||
"benchmark": "2.1.2",
|
"benchmark": "2.1.2",
|
||||||
"coveralls": "2.11.15",
|
"coveralls": "2.11.15",
|
||||||
|
|
|
@ -18,7 +18,10 @@ export default async function createCompiler (dir, { dev = false } = {}) {
|
||||||
ignore: 'pages/_document.js'
|
ignore: 'pages/_document.js'
|
||||||
})
|
})
|
||||||
|
|
||||||
const entry = {}
|
const entry = {
|
||||||
|
'main.js': dev ? require.resolve('../../client/next-dev') : require.resolve('../../client/next')
|
||||||
|
}
|
||||||
|
|
||||||
const defaultEntries = dev
|
const defaultEntries = dev
|
||||||
? [join(__dirname, '..', '..', 'client/webpack-hot-middleware-client')] : []
|
? [join(__dirname, '..', '..', 'client/webpack-hot-middleware-client')] : []
|
||||||
for (const p of pages) {
|
for (const p of pages) {
|
||||||
|
@ -145,6 +148,7 @@ export default async function createCompiler (dir, { dev = false } = {}) {
|
||||||
alias: {
|
alias: {
|
||||||
'babel-runtime': babelRuntimePath,
|
'babel-runtime': babelRuntimePath,
|
||||||
react: require.resolve('react'),
|
react: require.resolve('react'),
|
||||||
|
'react-dom': require.resolve('react-dom'),
|
||||||
'next/link': require.resolve('../../lib/link'),
|
'next/link': require.resolve('../../lib/link'),
|
||||||
'next/prefetch': require.resolve('../../lib/prefetch'),
|
'next/prefetch': require.resolve('../../lib/prefetch'),
|
||||||
'next/css': require.resolve('../../lib/css'),
|
'next/css': require.resolve('../../lib/css'),
|
||||||
|
@ -179,22 +183,6 @@ export default async function createCompiler (dir, { dev = false } = {}) {
|
||||||
return `webpack:///${resourcePath}?${id}`
|
return `webpack:///${resourcePath}?${id}`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
externals: [
|
|
||||||
'react',
|
|
||||||
'react-dom',
|
|
||||||
{
|
|
||||||
[require.resolve('react')]: 'react',
|
|
||||||
[require.resolve('../../lib/link')]: 'next/link',
|
|
||||||
[require.resolve('../../lib/prefetch')]: 'next/prefetch',
|
|
||||||
[require.resolve('../../lib/css')]: 'next/css',
|
|
||||||
[require.resolve('../../lib/head')]: 'next/head',
|
|
||||||
// React addons ask for React like this.
|
|
||||||
// That causes webpack to push react into the app's bundle.
|
|
||||||
// This fix simply prevents that and ask to use React from the next-bundle
|
|
||||||
'./React': 'react',
|
|
||||||
'./ReactDOM': 'react-dom'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
resolve: {
|
resolve: {
|
||||||
root: [
|
root: [
|
||||||
nodeModulesDir,
|
nodeModulesDir,
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { readFile } from 'mz/fs'
|
||||||
|
|
||||||
const cache = new Map()
|
const cache = new Map()
|
||||||
|
|
||||||
const defaultConfig = { cdn: true }
|
const defaultConfig = {}
|
||||||
|
|
||||||
export default function getConfig (dir) {
|
export default function getConfig (dir) {
|
||||||
if (!cache.has(dir)) {
|
if (!cache.has(dir)) {
|
||||||
|
|
|
@ -1,12 +1,6 @@
|
||||||
import React, { Component, PropTypes } from 'react'
|
import React, { Component, PropTypes } from 'react'
|
||||||
import htmlescape from 'htmlescape'
|
import htmlescape from 'htmlescape'
|
||||||
import { renderStatic } from 'glamor/server'
|
import { renderStatic } from 'glamor/server'
|
||||||
import readPkgUp from 'read-pkg-up'
|
|
||||||
|
|
||||||
const { pkg } = readPkgUp.sync({
|
|
||||||
cwd: __dirname,
|
|
||||||
normalize: false
|
|
||||||
})
|
|
||||||
|
|
||||||
export default class Document extends Component {
|
export default class Document extends Component {
|
||||||
static getInitialProps ({ renderPage }) {
|
static getInitialProps ({ renderPage }) {
|
||||||
|
@ -82,37 +76,11 @@ export class NextScript extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { staticMarkup, dev, cdn } = this.context._documentProps
|
const { staticMarkup } = this.context._documentProps
|
||||||
|
|
||||||
return <div>
|
return <div>
|
||||||
{staticMarkup ? null : createClientScript({ dev, cdn })}
|
{ staticMarkup ? null : <script type='text/javascript' src='/_next/commons.js' /> }
|
||||||
<script type='text/javascript' src='/_next/commons.js' />
|
{ staticMarkup ? null : <script type='text/javascript' src='/_next/main.js' /> }
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function createClientScript ({ dev, cdn }) {
|
|
||||||
if (dev) {
|
|
||||||
return <script type='text/javascript' src='/_next/next-dev.bundle.js' />
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cdn) {
|
|
||||||
return <script type='text/javascript' src='/_next/next.bundle.js' />
|
|
||||||
}
|
|
||||||
|
|
||||||
return <script dangerouslySetInnerHTML={{ __html: `
|
|
||||||
(function () {
|
|
||||||
load('https://cdn.zeit.co/next.js/${pkg.version}/next.min.js', function (err) {
|
|
||||||
if (err) load('/_next/next.bundle.js')
|
|
||||||
})
|
|
||||||
function load (src, fn) {
|
|
||||||
fn = fn || function () {}
|
|
||||||
var script = document.createElement('script')
|
|
||||||
script.src = src
|
|
||||||
script.onload = function () { fn(null) }
|
|
||||||
script.onerror = fn
|
|
||||||
script.crossorigin = 'anonymous'
|
|
||||||
document.body.appendChild(script)
|
|
||||||
}
|
|
||||||
})()
|
|
||||||
`}} />
|
|
||||||
}
|
|
||||||
|
|
|
@ -55,6 +55,11 @@ export default class Server {
|
||||||
await this.serveStatic(req, res, p)
|
await this.serveStatic(req, res, p)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
this.router.get('/_next/main.js', async (req, res, params) => {
|
||||||
|
const p = join(this.dir, '.next/main.js')
|
||||||
|
await this.serveStatic(req, res, p)
|
||||||
|
})
|
||||||
|
|
||||||
this.router.get('/_next/commons.js', async (req, res, params) => {
|
this.router.get('/_next/commons.js', async (req, res, params) => {
|
||||||
const p = join(this.dir, '.next/commons.js')
|
const p = join(this.dir, '.next/commons.js')
|
||||||
await this.serveStatic(req, res, p)
|
await this.serveStatic(req, res, p)
|
||||||
|
|
|
@ -3,7 +3,6 @@ import { createElement } from 'react'
|
||||||
import { renderToString, renderToStaticMarkup } from 'react-dom/server'
|
import { renderToString, renderToStaticMarkup } from 'react-dom/server'
|
||||||
import requireModule from './require'
|
import requireModule from './require'
|
||||||
import read from './read'
|
import read from './read'
|
||||||
import getConfig from './config'
|
|
||||||
import Router from '../lib/router'
|
import Router from '../lib/router'
|
||||||
import Head, { defaultHead } from '../lib/head'
|
import Head, { defaultHead } from '../lib/head'
|
||||||
import App from '../lib/app'
|
import App from '../lib/app'
|
||||||
|
@ -67,8 +66,6 @@ async function doRender (req, res, pathname, query, {
|
||||||
return { html, head }
|
return { html, head }
|
||||||
}
|
}
|
||||||
|
|
||||||
const config = await getConfig(dir)
|
|
||||||
|
|
||||||
const docProps = await Document.getInitialProps({ ...ctx, renderPage })
|
const docProps = await Document.getInitialProps({ ...ctx, renderPage })
|
||||||
|
|
||||||
const doc = createElement(Document, {
|
const doc = createElement(Document, {
|
||||||
|
@ -82,7 +79,6 @@ async function doRender (req, res, pathname, query, {
|
||||||
},
|
},
|
||||||
dev,
|
dev,
|
||||||
staticMarkup,
|
staticMarkup,
|
||||||
cdn: config.cdn,
|
|
||||||
...docProps
|
...docProps
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
import { join } from 'path'
|
import { join } from 'path'
|
||||||
import next from '../server/next'
|
import next from '../dist/server/next'
|
||||||
|
|
||||||
const dir = join(__dirname, 'fixtures', 'basic')
|
const dir = join(__dirname, 'fixtures', 'basic')
|
||||||
const app = next({
|
const app = next({
|
||||||
|
|
Loading…
Reference in a new issue