diff --git a/build/webpack.js b/build/webpack.js
index b210726d3a0d0..303354c973c20 100644
--- a/build/webpack.js
+++ b/build/webpack.js
@@ -126,6 +126,8 @@ export default async function getBaseWebpackConfig (dir: string, {dev = false, i
.filter((p) => !!p)
const outputPath = path.join(dir, config.distDir, isServer ? SERVER_DIRECTORY : '')
+
+
const pagesEntries = await getPages(dir, {nextPagesDir: DEFAULT_PAGES_DIR, dev, buildId, isServer, pageExtensions: config.pageExtensions.join('|')})
const totalPages = Object.keys(pagesEntries).length
const clientEntries = !isServer ? {
diff --git a/client/index.js b/client/index.js
index 2707ff40746b7..7d46a35e4661f 100644
--- a/client/index.js
+++ b/client/index.js
@@ -28,12 +28,16 @@ const {
query,
buildId,
assetPrefix,
- runtimeConfig
+ basePath,
+ runtimeConfig,
},
location
} = window
-const prefix = assetPrefix || ''
+
+console.log('Yupiii', basePath);
+
+const prefix = assetPrefix || '/account' || ''
// With dynamic assetPrefix it's no longer possible to set assetPrefix at the build time
// So, this is how we do it in the client side at runtime
@@ -48,7 +52,7 @@ envConfig.setConfig({
const asPath = getURL()
-const pageLoader = new PageLoader(buildId, prefix)
+const pageLoader = new PageLoader(buildId, prefix, basePath)
window.__NEXT_LOADED_PAGES__.forEach(({ route, fn }) => {
pageLoader.registerPage(route, fn)
})
@@ -99,7 +103,8 @@ export default async ({
App,
Component,
ErrorComponent,
- err: initialErr
+ err: initialErr,
+ basePath,
})
router.subscribe(({ App, Component, props, hash, err }) => {
diff --git a/client/next-dev.js b/client/next-dev.js
index 5aa14972a7a10..29a38b5ed701a 100644
--- a/client/next-dev.js
+++ b/client/next-dev.js
@@ -14,7 +14,7 @@ const {
}
} = window
-const prefix = assetPrefix || ''
+const prefix = assetPrefix || '/account' || ''
const webpackHMR = initWebpackHMR({assetPrefix: prefix})
window.next = next
diff --git a/client/webpack-hot-middleware-client.js b/client/webpack-hot-middleware-client.js
index 8331a3982dd7f..9570a879e848e 100644
--- a/client/webpack-hot-middleware-client.js
+++ b/client/webpack-hot-middleware-client.js
@@ -62,7 +62,7 @@ const handlers = {
export default ({assetPrefix}) => {
const options = {
- path: `${assetPrefix}/_next/webpack-hmr`
+ path: `${assetPrefix || '/account'}/_next/webpack-hmr`
}
const devClient = connect(options)
diff --git a/examples/with-zones/.babelrc b/examples/with-zones/.babelrc
new file mode 100644
index 0000000000000..1e671b68f76b8
--- /dev/null
+++ b/examples/with-zones/.babelrc
@@ -0,0 +1,4 @@
+{
+ "presets": ["next/babel"],
+ "plugins": []
+ }
diff --git a/examples/with-zones/account/.gitignore b/examples/with-zones/account/.gitignore
new file mode 100644
index 0000000000000..f74c78183c917
--- /dev/null
+++ b/examples/with-zones/account/.gitignore
@@ -0,0 +1,2 @@
+.next
+node_modules
diff --git a/examples/with-zones/account/next.config.js b/examples/with-zones/account/next.config.js
new file mode 100644
index 0000000000000..2c68eb8c98579
--- /dev/null
+++ b/examples/with-zones/account/next.config.js
@@ -0,0 +1,7 @@
+const { NOW_URL } = process.env
+const { alias } = require('./now.json')
+
+module.exports = {
+ // assetPrefix: NOW_URL ? `https://${alias}` : 'http://localhost:3000',
+ basePath: '/account',
+}
diff --git a/examples/with-zones/account/now.json b/examples/with-zones/account/now.json
new file mode 100644
index 0000000000000..3c3113c5bada7
--- /dev/null
+++ b/examples/with-zones/account/now.json
@@ -0,0 +1,3 @@
+{
+ "alias": "with-zones-account.now.sh"
+}
diff --git a/examples/with-zones/account/package.json b/examples/with-zones/account/package.json
new file mode 100644
index 0000000000000..e6f706850c596
--- /dev/null
+++ b/examples/with-zones/account/package.json
@@ -0,0 +1,14 @@
+{
+ "name": "with-zones-account",
+ "version": "1.0.0",
+ "scripts": {
+ "build": "next build",
+ "start": "next start -p 3000"
+ },
+ "dependencies": {
+ "next": "latest",
+ "react": "^16.0.0",
+ "react-dom": "^16.0.0"
+ },
+ "license": "ISC"
+}
diff --git a/examples/with-zones/account/pages/_app.js b/examples/with-zones/account/pages/_app.js
new file mode 100644
index 0000000000000..7519b47b3b5bf
--- /dev/null
+++ b/examples/with-zones/account/pages/_app.js
@@ -0,0 +1,25 @@
+import App, {Container} from 'next/app'
+import React from 'react'
+import Link from "next/link";
+
+export default class MyApp extends App {
+ static async getInitialProps ({ Component, router, ctx }) {
+ let pageProps = {}
+
+ if (Component.getInitialProps) {
+ pageProps = await Component.getInitialProps(ctx)
+ }
+
+ return {pageProps}
+ }
+
+ render () {
+ const {Component, pageProps} = this.props
+ return
+ password
+
This is our homepage
+ ) diff --git a/examples/with-zones/package.json b/examples/with-zones/package.json index a24bbcea0807b..09e105232c453 100644 --- a/examples/with-zones/package.json +++ b/examples/with-zones/package.json @@ -8,6 +8,9 @@ "blog": "next blog -p 5000", "blog-build": "next build blog", "blog-start": "next start blog -p 5000", + "account": "next account -p 3000", + "account-build": "next build account", + "account-start": "next start account -p 3000", "proxy": "micro-proxy -r rules-dev.json" }, "dependencies": { diff --git a/examples/with-zones/rules-dev.json b/examples/with-zones/rules-dev.json index 680a330286beb..1a9734b2bf3ac 100644 --- a/examples/with-zones/rules-dev.json +++ b/examples/with-zones/rules-dev.json @@ -1,6 +1,7 @@ { "rules": [ {"pathname": "/blog", "method":["GET", "POST", "OPTIONS"], "dest": "http://localhost:5000"}, + {"pathname": "/account", "dest": "http://localhost:3000"}, {"pathname": "/**", "dest": "http://localhost:4000"} ] } diff --git a/lib/asset.js b/lib/asset.js index caa41b7e96aa4..c1e761b54d58f 100644 --- a/lib/asset.js +++ b/lib/asset.js @@ -7,7 +7,7 @@ export default function asset (path) { } const pathWithoutSlash = path.replace(/^\//, '') - return `${assetPrefix || ''}/static/${pathWithoutSlash}` + return `${assetPrefix || '/account' || ''}/static/${pathWithoutSlash}` } export function setAssetPrefix (url) { diff --git a/lib/page-loader.js b/lib/page-loader.js index 938d3c8f8303b..79b217adc1aca 100644 --- a/lib/page-loader.js +++ b/lib/page-loader.js @@ -4,9 +4,10 @@ import EventEmitter from './EventEmitter' const webpackModule = module export default class PageLoader { - constructor (buildId, assetPrefix) { + constructor (buildId, assetPrefix, basePath) { this.buildId = buildId this.assetPrefix = assetPrefix + this.basePath = basePath this.pageCache = {} this.pageLoadedHandlers = {} @@ -25,6 +26,7 @@ export default class PageLoader { } loadPage (route) { + console.log('loadPage', route) route = this.normalizeRoute(route) return new Promise((resolve, reject) => { @@ -69,7 +71,8 @@ export default class PageLoader { const scriptRoute = route === '/' ? '/index.js' : `${route}.js` const script = document.createElement('script') - const url = `${this.assetPrefix}/_next/static/${encodeURIComponent(this.buildId)}/pages${scriptRoute}` + const url = `${this.assetPrefix || this.basePath}/_next/static/${encodeURIComponent(this.buildId)}/pages${scriptRoute}` + console.log('loadScript', this.basePath, url); script.src = url script.onerror = () => { const error = new Error(`Error when loading route: ${route}`) diff --git a/lib/router/router.js b/lib/router/router.js index 0941273d6992a..631cd2e897b15 100644 --- a/lib/router/router.js +++ b/lib/router/router.js @@ -17,8 +17,9 @@ const historyMethodWarning = execOnce((method) => { export default class Router { static events = new EventEmitter() - constructor (pathname, query, as, { initialProps, pageLoader, App, Component, ErrorComponent, err } = {}) { + constructor (pathname, query, as, { initialProps, pageLoader, App, Component, ErrorComponent, err, basePath } = {}) { // represents the current component key + console.log('Initializing router', basePath) this.route = toRoute(pathname) // set up the component cache (by route keys) @@ -44,6 +45,7 @@ export default class Router { this.asPath = as this.subscriptions = new Set() this.componentLoadCancel = null + this.basePath = basePath this._beforePopState = () => true if (typeof window !== 'undefined') { @@ -255,7 +257,7 @@ export default class Router { // 3. Internal error while loading the page // So, doing a hard reload is the proper way to deal with this. - window.location.href = as + // window.location.href = as // Changing the URL doesn't block executing the current code path. // So, we need to mark it as a cancelled error and stop the routing logic. @@ -355,6 +357,10 @@ export default class Router { } async fetchComponent (route, as) { + route = route.replace(this.basePath, '') + if ( route === '') { + route = '/' + } let cancelled = false const cancel = this.componentLoadCancel = function () { cancelled = true diff --git a/package.json b/package.json index 4f13456b7444e..5e120505bd52c 100644 --- a/package.json +++ b/package.json @@ -39,8 +39,7 @@ "coveralls": "nyc --instrument=false --source-map=false report --temp-directory=./coverage --reporter=text-lcov | coveralls", "flow": "flow check", "lint": "standard 'bin/*' 'client/**/*.js' 'examples/**/*.js' 'lib/**/*.js' 'pages/**/*.js' 'server/**/*.js' 'build/**/*.js' 'test/**/*.js'", - "prepublish": "npm run release", - "precommit": "lint-staged" + "prepublish": "npm run release" }, "standard": { "parser": "babel-eslint", diff --git a/server/document.js b/server/document.js index 0f74b1c77cf9d..c8e8bc20febd3 100644 --- a/server/document.js +++ b/server/document.js @@ -44,11 +44,11 @@ export class Head extends Component { } getCssLinks () { - const { assetPrefix, files } = this.context._documentProps + const { assetPrefix, basePath, files } = this.context._documentProps if(!files || files.length === 0) { return null } - + return files.map((file) => { // Only render .css files here if(!/\.css$/.exec(file)) { @@ -59,18 +59,18 @@ export class Head extends Component { key={file} nonce={this.props.nonce} rel='stylesheet' - href={`${assetPrefix}/_next/${file}`} + href={`${assetPrefix || basePath}/_next/${file}`} /> }) } getPreloadDynamicChunks () { - const { dynamicImports, assetPrefix } = this.context._documentProps + const { dynamicImports, assetPrefix, basePath } = this.context._documentProps return dynamicImports.map((bundle) => { return @@ -78,11 +78,11 @@ export class Head extends Component { } getPreloadMainLinks () { - const { assetPrefix, files } = this.context._documentProps + const { assetPrefix, basePath, files } = this.context._documentProps if(!files || files.length === 0) { return null } - + return files.map((file) => { // Only render .js files here if(!/\.js$/.exec(file)) { @@ -93,22 +93,22 @@ export class Head extends Component { key={file} nonce={this.props.nonce} rel='preload' - href={`${assetPrefix}/_next/${file}`} + href={`${assetPrefix || basePath}/_next/${file}`} as='script' /> }) } render () { - const { head, styles, assetPrefix, __NEXT_DATA__ } = this.context._documentProps + const { head, styles, assetPrefix, basePath, __NEXT_DATA__ } = this.context._documentProps const { page, pathname, buildId } = __NEXT_DATA__ const pagePathname = getPagePathname(pathname) return {(head || []).map((h, i) => React.cloneElement(h, { key: h.key || i }))} - {page !== '/_error' && } - - + {page !== '/_error' && } + + {this.getPreloadDynamicChunks()} {this.getPreloadMainLinks()} {this.getCssLinks()} @@ -144,23 +144,23 @@ export class NextScript extends Component { } getDynamicChunks () { - const { dynamicImports, assetPrefix } = this.context._documentProps + const { dynamicImports, assetPrefix, basePath } = this.context._documentProps return dynamicImports.map((bundle) => { return }) } getScripts () { - const { assetPrefix, files } = this.context._documentProps + const { assetPrefix, basePath, files } = this.context._documentProps if(!files || files.length === 0) { return null } - + return files.map((file) => { // Only render .js files here if(!/\.js$/.exec(file)) { @@ -169,7 +169,7 @@ export class NextScript extends Component { return @@ -199,18 +199,18 @@ export class NextScript extends Component { } render () { - const { staticMarkup, assetPrefix, devFiles, __NEXT_DATA__ } = this.context._documentProps + const { staticMarkup, assetPrefix, basePath, devFiles, __NEXT_DATA__ } = this.context._documentProps const { page, pathname, buildId } = __NEXT_DATA__ const pagePathname = getPagePathname(pathname) return