1
0
Fork 0
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:
Arunoda Susiripala 2016-12-17 14:19:10 +05:30 committed by Naoyuki Kanezawa
parent 59d514e071
commit b62a0e8f55
12 changed files with 20 additions and 160 deletions

View file

@ -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

View file

@ -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

View file

@ -12,8 +12,5 @@
"next": "*" "next": "*"
}, },
"author": "", "author": "",
"license": "ISC", "license": "ISC"
"next": {
"cdn": true
}
} }

View file

@ -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,

View file

@ -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
} }

View file

@ -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",

View file

@ -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,

View file

@ -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)) {

View file

@ -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)
}
})()
`}} />
}

View file

@ -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)

View file

@ -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
}) })

View file

@ -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({