From b71bc641a05850aa6b3a7e0f53e3901650231488 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Fri, 8 Jun 2018 11:24:59 +0200 Subject: [PATCH 01/16] Move build directory outside of server folder --- babel.js | 2 +- bin/next-build | 2 +- .../babel/plugins/handle-import.js | 0 {server/build => build}/babel/preset.js | 0 {server/build => build}/index.js | 4 ++-- .../build => build}/loaders/emit-file-loader.js | 0 .../loaders/hot-self-accept-loader.js | 0 .../loaders/next-babel-loader.js | 0 .../plugins/build-manifest-plugin.js | 2 +- .../plugins/dynamic-chunks-plugin.js | 0 .../plugins/nextjs-ssr-import.js | 0 .../plugins/pages-manifest-plugin.js | 3 +-- {server/build => build}/plugins/pages-plugin.js | 2 +- .../plugins/unlink-file-plugin.js | 2 +- {server/build => build}/webpack.js | 17 +++++++++-------- {server/build => build}/webpack/utils.js | 0 lib/constants.js | 2 ++ {server/lib => lib}/promisify.js | 0 server/hot-reloader.js | 2 +- server/index.js | 2 +- server/on-demand-entry-handler.js | 6 +++--- server/utils.js | 3 --- taskfile.js | 8 +++++++- 23 files changed, 31 insertions(+), 26 deletions(-) rename {server/build => build}/babel/plugins/handle-import.js (100%) rename {server/build => build}/babel/preset.js (100%) rename {server/build => build}/index.js (93%) rename {server/build => build}/loaders/emit-file-loader.js (100%) rename {server/build => build}/loaders/hot-self-accept-loader.js (100%) rename {server/build => build}/loaders/next-babel-loader.js (100%) rename {server/build => build}/plugins/build-manifest-plugin.js (95%) rename {server/build => build}/plugins/dynamic-chunks-plugin.js (100%) rename {server/build => build}/plugins/nextjs-ssr-import.js (100%) rename {server/build => build}/plugins/pages-manifest-plugin.js (90%) rename {server/build => build}/plugins/pages-plugin.js (97%) rename {server/build => build}/plugins/unlink-file-plugin.js (93%) rename {server/build => build}/webpack.js (93%) rename {server/build => build}/webpack/utils.js (100%) rename {server/lib => lib}/promisify.js (100%) diff --git a/babel.js b/babel.js index 88817fc616c8b..1bbe4f360f180 100644 --- a/babel.js +++ b/babel.js @@ -1 +1 @@ -module.exports = require('./dist/server/build/babel/preset') +module.exports = require('./dist/build/babel/preset') diff --git a/bin/next-build b/bin/next-build index eb60720e6ab36..7d518777565bf 100755 --- a/bin/next-build +++ b/bin/next-build @@ -2,7 +2,7 @@ import { resolve, join } from 'path' import { existsSync } from 'fs' import parseArgs from 'minimist' -import build from '../server/build' +import build from '../build' import { printAndExit } from '../lib/utils' const argv = parseArgs(process.argv.slice(2), { diff --git a/server/build/babel/plugins/handle-import.js b/build/babel/plugins/handle-import.js similarity index 100% rename from server/build/babel/plugins/handle-import.js rename to build/babel/plugins/handle-import.js diff --git a/server/build/babel/preset.js b/build/babel/preset.js similarity index 100% rename from server/build/babel/preset.js rename to build/babel/preset.js diff --git a/server/build/index.js b/build/index.js similarity index 93% rename from server/build/index.js rename to build/index.js index 809240b6aa4b3..2e0a7dd55f3c1 100644 --- a/server/build/index.js +++ b/build/index.js @@ -2,8 +2,8 @@ import { join } from 'path' import promisify from '../lib/promisify' import fs from 'fs' import webpack from 'webpack' -import loadConfig from '../config' -import { PHASE_PRODUCTION_BUILD, BUILD_ID_FILE } from '../../lib/constants' +import loadConfig from '../server/config' +import { PHASE_PRODUCTION_BUILD, BUILD_ID_FILE } from '../lib/constants' import getBaseWebpackConfig from './webpack' const access = promisify(fs.access) diff --git a/server/build/loaders/emit-file-loader.js b/build/loaders/emit-file-loader.js similarity index 100% rename from server/build/loaders/emit-file-loader.js rename to build/loaders/emit-file-loader.js diff --git a/server/build/loaders/hot-self-accept-loader.js b/build/loaders/hot-self-accept-loader.js similarity index 100% rename from server/build/loaders/hot-self-accept-loader.js rename to build/loaders/hot-self-accept-loader.js diff --git a/server/build/loaders/next-babel-loader.js b/build/loaders/next-babel-loader.js similarity index 100% rename from server/build/loaders/next-babel-loader.js rename to build/loaders/next-babel-loader.js diff --git a/server/build/plugins/build-manifest-plugin.js b/build/plugins/build-manifest-plugin.js similarity index 95% rename from server/build/plugins/build-manifest-plugin.js rename to build/plugins/build-manifest-plugin.js index be2e5fee26ff7..3336eb3d6a66f 100644 --- a/server/build/plugins/build-manifest-plugin.js +++ b/build/plugins/build-manifest-plugin.js @@ -1,6 +1,6 @@ // @flow import { RawSource } from 'webpack-sources' -import {BUILD_MANIFEST} from '../../../lib/constants' +import {BUILD_MANIFEST} from '../../lib/constants' // This plugin creates a build-manifest.json for all assets that are being output // It has a mapping of "entry" filename to real filename. Because the real filename can be hashed in production diff --git a/server/build/plugins/dynamic-chunks-plugin.js b/build/plugins/dynamic-chunks-plugin.js similarity index 100% rename from server/build/plugins/dynamic-chunks-plugin.js rename to build/plugins/dynamic-chunks-plugin.js diff --git a/server/build/plugins/nextjs-ssr-import.js b/build/plugins/nextjs-ssr-import.js similarity index 100% rename from server/build/plugins/nextjs-ssr-import.js rename to build/plugins/nextjs-ssr-import.js diff --git a/server/build/plugins/pages-manifest-plugin.js b/build/plugins/pages-manifest-plugin.js similarity index 90% rename from server/build/plugins/pages-manifest-plugin.js rename to build/plugins/pages-manifest-plugin.js index 8f9e265b4d063..54f1a81593058 100644 --- a/server/build/plugins/pages-manifest-plugin.js +++ b/build/plugins/pages-manifest-plugin.js @@ -1,7 +1,6 @@ // @flow import { RawSource } from 'webpack-sources' -import { MATCH_ROUTE_NAME } from '../../utils' -import {PAGES_MANIFEST} from '../../../lib/constants' +import {PAGES_MANIFEST, MATCH_ROUTE_NAME} from '../../lib/constants' // This plugin creates a pages-manifest.json from page entrypoints. // This is used for mapping paths like `/` to `.next/dist/bundles/pages/index.js` when doing SSR diff --git a/server/build/plugins/pages-plugin.js b/build/plugins/pages-plugin.js similarity index 97% rename from server/build/plugins/pages-plugin.js rename to build/plugins/pages-plugin.js index c838df2a3d192..4b5548e273fea 100644 --- a/server/build/plugins/pages-plugin.js +++ b/build/plugins/pages-plugin.js @@ -2,7 +2,7 @@ import { ConcatSource } from 'webpack-sources' import { IS_BUNDLED_PAGE, MATCH_ROUTE_NAME -} from '../../utils' +} from '../../lib/constants' class PageChunkTemplatePlugin { apply (chunkTemplate) { diff --git a/server/build/plugins/unlink-file-plugin.js b/build/plugins/unlink-file-plugin.js similarity index 93% rename from server/build/plugins/unlink-file-plugin.js rename to build/plugins/unlink-file-plugin.js index 096bda98a8bea..8497a924b3c50 100644 --- a/server/build/plugins/unlink-file-plugin.js +++ b/build/plugins/unlink-file-plugin.js @@ -1,7 +1,7 @@ import { join } from 'path' import promisify from '../../lib/promisify' import fs from 'fs' -import { IS_BUNDLED_PAGE } from '../../utils' +import { IS_BUNDLED_PAGE } from '../../lib/constants' const unlink = promisify(fs.unlink) diff --git a/server/build/webpack.js b/build/webpack.js similarity index 93% rename from server/build/webpack.js rename to build/webpack.js index 6e4a6d228be2e..78f4c812a3efa 100644 --- a/server/build/webpack.js +++ b/build/webpack.js @@ -12,11 +12,12 @@ import DynamicChunksPlugin from './plugins/dynamic-chunks-plugin' import UnlinkFilePlugin from './plugins/unlink-file-plugin' import PagesManifestPlugin from './plugins/pages-manifest-plugin' import BuildManifestPlugin from './plugins/build-manifest-plugin' -import {SERVER_DIRECTORY} from '../../lib/constants' +import {SERVER_DIRECTORY} from '../lib/constants' -const nextDir = path.join(__dirname, '..', '..', '..') -const nextNodeModulesDir = path.join(nextDir, 'node_modules') -const nextPagesDir = path.join(nextDir, 'pages') +const nextDir = path.join(__dirname, '..') +const nextModuleDir = path.join(nextDir, '..') +const nextNodeModulesDir = path.join(nextModuleDir, 'node_modules') +const nextPagesDir = path.join(nextModuleDir, 'pages') function externalsConfig (dir, isServer) { const externals = [] @@ -69,9 +70,9 @@ export default async function getBaseWebpackConfig (dir, {dev = false, isServer const totalPages = Object.keys(pagesEntries).length const clientEntries = !isServer ? { 'main.js': [ - dev && !isServer && path.join(__dirname, '..', '..', 'client', 'webpack-hot-middleware-client'), - dev && !isServer && path.join(__dirname, '..', '..', 'client', 'on-demand-entries-client'), - require.resolve(`../../client/next${dev ? '-dev' : ''}`) + dev && !isServer && path.join(nextDir, 'client', 'webpack-hot-middleware-client'), + dev && !isServer && path.join(nextDir, 'client', 'on-demand-entries-client'), + path.join(nextDir, 'client', `next${dev ? '-dev' : ''}`) ].filter(Boolean) } : {} @@ -107,7 +108,7 @@ export default async function getBaseWebpackConfig (dir, {dev = false, isServer ...nodePathList // Support for NODE_PATH environment variable ], alias: { - next: nextDir + next: nextModuleDir } }, resolveLoader: { diff --git a/server/build/webpack/utils.js b/build/webpack/utils.js similarity index 100% rename from server/build/webpack/utils.js rename to build/webpack/utils.js diff --git a/lib/constants.js b/lib/constants.js index 6888a5f2b5186..c11392b2306bb 100644 --- a/lib/constants.js +++ b/lib/constants.js @@ -12,3 +12,5 @@ export const BLOCKED_PAGES = [ '/_app', '/_error' ] +export const IS_BUNDLED_PAGE = /^bundles[/\\]pages.*\.js$/ +export const MATCH_ROUTE_NAME = /^bundles[/\\]pages[/\\](.*)\.js$/ diff --git a/server/lib/promisify.js b/lib/promisify.js similarity index 100% rename from server/lib/promisify.js rename to lib/promisify.js diff --git a/server/hot-reloader.js b/server/hot-reloader.js index 4fb1b0fb88663..b9ef639dd07e8 100644 --- a/server/hot-reloader.js +++ b/server/hot-reloader.js @@ -7,9 +7,9 @@ import webpack from 'webpack' import getBaseWebpackConfig from './build/webpack' import UUID from 'uuid' import { - IS_BUNDLED_PAGE, addCorsSupport } from './utils' +import {IS_BUNDLED_PAGE} from '../lib/constants' export default class HotReloader { constructor (dir, { quiet, config } = {}) { diff --git a/server/index.js b/server/index.js index 01dd8ee4d0fae..4fa1d623556ef 100644 --- a/server/index.js +++ b/server/index.js @@ -4,7 +4,7 @@ import { parse as parseUrl } from 'url' import { parse as parseQs } from 'querystring' import fs from 'fs' import http, { STATUS_CODES } from 'http' -import promisify from './lib/promisify' +import promisify from '../lib/promisify' import { renderToHTML, renderErrorToHTML, diff --git a/server/on-demand-entry-handler.js b/server/on-demand-entry-handler.js index 66e83a3bb97ab..1ce1d6e4ab02c 100644 --- a/server/on-demand-entry-handler.js +++ b/server/on-demand-entry-handler.js @@ -3,11 +3,11 @@ import { EventEmitter } from 'events' import { join } from 'path' import { parse } from 'url' import touch from 'touch' -import promisify from './lib/promisify' +import promisify from '../lib/promisify' import globModule from 'glob' import {normalizePagePath, pageNotFoundError} from './require' -import {createEntry} from './build/webpack/utils' -import { MATCH_ROUTE_NAME, IS_BUNDLED_PAGE } from './utils' +import {createEntry} from '../build/webpack/utils' +import { MATCH_ROUTE_NAME, IS_BUNDLED_PAGE } from '../lib/constants' const ADDED = Symbol('added') const BUILDING = Symbol('building') diff --git a/server/utils.js b/server/utils.js index a233aeb861193..0d8f39e3c113b 100644 --- a/server/utils.js +++ b/server/utils.js @@ -1,9 +1,6 @@ import { join } from 'path' import { readdirSync, existsSync } from 'fs' -export const IS_BUNDLED_PAGE = /^bundles[/\\]pages.*\.js$/ -export const MATCH_ROUTE_NAME = /^bundles[/\\]pages[/\\](.*)\.js$/ - export function getAvailableChunks (distDir) { const chunksDir = join(distDir, 'chunks') if (!existsSync(chunksDir)) return {} diff --git a/taskfile.js b/taskfile.js index 577a0fcd3d2e8..0edd131d77738 100644 --- a/taskfile.js +++ b/taskfile.js @@ -5,7 +5,7 @@ const mkdirp = require('mkdirp') const isWindows = /^win/.test(process.platform) export async function compile (task) { - await task.parallel(['bin', 'server', 'lib', 'client']) + await task.parallel(['bin', 'server', 'nextbuild', 'lib', 'client']) } export async function bin (task, opts) { @@ -23,6 +23,11 @@ export async function server (task, opts) { notify('Compiled server files') } +export async function nextbuild (task, opts) { + await task.source(opts.src || 'build/**/*.js').babel().target('dist/build') + notify('Compiled build files') +} + export async function client (task, opts) { await task.source(opts.src || 'client/**/*.js').babel().target('dist/client') notify('Compiled client files') @@ -50,6 +55,7 @@ export default async function (task) { await task.watch('bin/*', 'bin') await task.watch('pages/**/*.js', 'copy') await task.watch('server/**/*.js', 'server') + await task.watch('build/**/*.js', 'nextbuild') await task.watch('client/**/*.js', 'client') await task.watch('lib/**/*.js', 'lib') } From 9a4bbe73f6116b5d075d88b95a2334243b11cff9 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Fri, 8 Jun 2018 11:48:48 +0200 Subject: [PATCH 02/16] Fix reference to promisify --- server/lib/source-map-support.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/lib/source-map-support.js b/server/lib/source-map-support.js index fdd6c466719a4..1d0bb9120bee8 100644 --- a/server/lib/source-map-support.js +++ b/server/lib/source-map-support.js @@ -28,7 +28,7 @@ async function rewriteTraceLine (trace: string): Promise { // Load these on demand. const fs = require('fs') - const promisify = require('./promisify') + const promisify = require('../../lib/promisify') const readFile = promisify(fs.readFile) const access = promisify(fs.access) From c7cadeee2c71465e614f17f0ab4dc1db7601a650 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Fri, 8 Jun 2018 11:56:05 +0200 Subject: [PATCH 03/16] Load from the right location --- test/isolated/webpack-utils.test.js | 2 +- test/lib/next-test-utils.js | 2 +- test/unit/handle-import-babel-plugin.test.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/isolated/webpack-utils.test.js b/test/isolated/webpack-utils.test.js index f73de78d8ec88..cb1f7f047ef28 100644 --- a/test/isolated/webpack-utils.test.js +++ b/test/isolated/webpack-utils.test.js @@ -1,7 +1,7 @@ /* global describe, it, expect */ import {normalize} from 'path' -import {getPageEntries, createEntry} from '../../dist/server/build/webpack/utils' +import {getPageEntries, createEntry} from '../../dist/build/webpack/utils' describe('createEntry', () => { it('Should turn a path into a page entry', () => { diff --git a/test/lib/next-test-utils.js b/test/lib/next-test-utils.js index 174b55b5e99fc..d2c54d461de04 100644 --- a/test/lib/next-test-utils.js +++ b/test/lib/next-test-utils.js @@ -9,7 +9,7 @@ import { readFileSync, writeFileSync, existsSync, unlinkSync } from 'fs' import fkill from 'fkill' import server from '../../dist/server/next' -import build from '../../dist/server/build' +import build from '../../dist/build' import _export from '../../dist/server/export' import _pkg from '../../package.json' diff --git a/test/unit/handle-import-babel-plugin.test.js b/test/unit/handle-import-babel-plugin.test.js index 48fb8a58b177a..543b27b6543ad 100644 --- a/test/unit/handle-import-babel-plugin.test.js +++ b/test/unit/handle-import-babel-plugin.test.js @@ -1,5 +1,5 @@ /* global describe, it, expect */ -import { getModulePath } from '../../dist/server/build/babel/plugins/handle-import' +import { getModulePath } from '../../dist/build/babel/plugins/handle-import' function cleanPath (mPath) { return mPath From 06d637bc8fbac4235d1db04cdfefb3dcf745cf82 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Fri, 8 Jun 2018 12:09:44 +0200 Subject: [PATCH 04/16] Load webpack config from new build directory --- server/hot-reloader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/hot-reloader.js b/server/hot-reloader.js index b9ef639dd07e8..a9a0ef221e85c 100644 --- a/server/hot-reloader.js +++ b/server/hot-reloader.js @@ -4,7 +4,7 @@ import WebpackHotMiddleware from 'webpack-hot-middleware' import del from 'del' import onDemandEntryHandler from './on-demand-entry-handler' import webpack from 'webpack' -import getBaseWebpackConfig from './build/webpack' +import getBaseWebpackConfig from '../build/webpack' import UUID from 'uuid' import { addCorsSupport From 9c9990a0cd6a1a23701a0b0334707a239829fb84 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Fri, 8 Jun 2018 15:05:38 +0200 Subject: [PATCH 05/16] Manage `nextPagesDir` in one place --- build/webpack.js | 2 +- build/webpack/utils.js | 8 +++----- test/isolated/webpack-utils.test.js | 14 ++++++++------ 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/build/webpack.js b/build/webpack.js index 3f6070b8f049a..3de1ddd608464 100644 --- a/build/webpack.js +++ b/build/webpack.js @@ -66,7 +66,7 @@ export default async function getBaseWebpackConfig (dir, {dev = false, isServer .split(process.platform === 'win32' ? ';' : ':') .filter((p) => !!p) - const pagesEntries = await getPages(dir, {dev, isServer, pageExtensions: config.pageExtensions.join('|')}) + const pagesEntries = await getPages(dir, {nextPagesDir, dev, isServer, pageExtensions: config.pageExtensions.join('|')}) const totalPages = Object.keys(pagesEntries).length const clientEntries = !isServer ? { 'main.js': [ diff --git a/build/webpack/utils.js b/build/webpack/utils.js index 960226543feea..76f752710669f 100644 --- a/build/webpack/utils.js +++ b/build/webpack/utils.js @@ -4,12 +4,10 @@ import globModule from 'glob' const glob = promisify(globModule) -const nextPagesDir = path.join(__dirname, '..', '..', '..', 'pages') - -export async function getPages (dir, {dev, isServer, pageExtensions}) { +export async function getPages (dir, {nextPagesDir, dev, isServer, pageExtensions}) { const pageFiles = await getPagePaths(dir, {dev, isServer, pageExtensions}) - return getPageEntries(pageFiles, {isServer, pageExtensions}) + return getPageEntries(pageFiles, {nextPagesDir, isServer, pageExtensions}) } export async function getPagePaths (dir, {dev, isServer, pageExtensions}) { @@ -50,7 +48,7 @@ export function createEntry (filePath, {name, pageExtensions} = {}) { } // Convert page paths into entries -export function getPageEntries (pagePaths, {isServer = false, pageExtensions} = {}) { +export function getPageEntries (pagePaths, {nextPagesDir, isServer = false, pageExtensions} = {}) { const entries = {} for (const filePath of pagePaths) { diff --git a/test/isolated/webpack-utils.test.js b/test/isolated/webpack-utils.test.js index cb1f7f047ef28..e206061ad20b2 100644 --- a/test/isolated/webpack-utils.test.js +++ b/test/isolated/webpack-utils.test.js @@ -1,6 +1,6 @@ /* global describe, it, expect */ -import {normalize} from 'path' +import {normalize, join} from 'path' import {getPageEntries, createEntry} from '../../dist/build/webpack/utils' describe('createEntry', () => { @@ -48,33 +48,35 @@ describe('createEntry', () => { }) describe('getPageEntries', () => { + const nextPagesDir = join(__dirname, '..', '..', 'dist', 'pages') + it('Should return paths', () => { const pagePaths = ['pages/index.js'] - const pageEntries = getPageEntries(pagePaths) + const pageEntries = getPageEntries(pagePaths, {nextPagesDir}) expect(pageEntries[normalize('bundles/pages/index.js')][0]).toBe('./pages/index.js') }) it('Should include default _error', () => { const pagePaths = ['pages/index.js'] - const pageEntries = getPageEntries(pagePaths) + const pageEntries = getPageEntries(pagePaths, {nextPagesDir}) expect(pageEntries[normalize('bundles/pages/_error.js')][0]).toMatch(/dist[/\\]pages[/\\]_error\.js/) }) it('Should not include default _error when _error.js is inside the pages directory', () => { const pagePaths = ['pages/index.js', 'pages/_error.js'] - const pageEntries = getPageEntries(pagePaths) + const pageEntries = getPageEntries(pagePaths, {nextPagesDir}) expect(pageEntries[normalize('bundles/pages/_error.js')][0]).toBe('./pages/_error.js') }) it('Should include default _document when isServer is true', () => { const pagePaths = ['pages/index.js'] - const pageEntries = getPageEntries(pagePaths, {isServer: true}) + const pageEntries = getPageEntries(pagePaths, {nextPagesDir, isServer: true}) expect(pageEntries[normalize('bundles/pages/_document.js')][0]).toMatch(/dist[/\\]pages[/\\]_document\.js/) }) it('Should not include default _document when _document.js is inside the pages directory', () => { const pagePaths = ['pages/index.js', 'pages/_document.js'] - const pageEntries = getPageEntries(pagePaths, {isServer: true}) + const pageEntries = getPageEntries(pagePaths, {nextPagesDir, isServer: true}) expect(pageEntries[normalize('bundles/pages/_document.js')][0]).toBe('./pages/_document.js') }) }) From 3173043c8cab7b8176d0dc26685016979e61865d Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Sat, 9 Jun 2018 17:54:25 +0200 Subject: [PATCH 06/16] Pass through the correct directories --- build/webpack.js | 23 +++++++++-------------- lib/constants.js | 4 ++++ 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/build/webpack.js b/build/webpack.js index 3de1ddd608464..058978a402d92 100644 --- a/build/webpack.js +++ b/build/webpack.js @@ -12,12 +12,7 @@ import DynamicChunksPlugin from './plugins/dynamic-chunks-plugin' import UnlinkFilePlugin from './plugins/unlink-file-plugin' import PagesManifestPlugin from './plugins/pages-manifest-plugin' import BuildManifestPlugin from './plugins/build-manifest-plugin' -import {SERVER_DIRECTORY} from '../lib/constants' - -const nextDir = path.join(__dirname, '..') -const nextModuleDir = path.join(nextDir, '..') -const nextNodeModulesDir = path.join(nextModuleDir, 'node_modules') -const nextPagesDir = path.join(nextModuleDir, 'pages') +import {SERVER_DIRECTORY, NEXT_PROJECT_ROOT, NEXT_PROJECT_ROOT_NODE_MODULES, DEFAULT_PAGES_DIR} from '../lib/constants' function externalsConfig (dir, isServer) { const externals = [] @@ -66,13 +61,13 @@ export default async function getBaseWebpackConfig (dir, {dev = false, isServer .split(process.platform === 'win32' ? ';' : ':') .filter((p) => !!p) - const pagesEntries = await getPages(dir, {nextPagesDir, dev, isServer, pageExtensions: config.pageExtensions.join('|')}) + const pagesEntries = await getPages(dir, {nextPagesDir: DEFAULT_PAGES_DIR, dev, isServer, pageExtensions: config.pageExtensions.join('|')}) const totalPages = Object.keys(pagesEntries).length const clientEntries = !isServer ? { 'main.js': [ - dev && !isServer && path.join(nextDir, 'client', 'webpack-hot-middleware-client'), - dev && !isServer && path.join(nextDir, 'client', 'on-demand-entries-client'), - path.join(nextDir, 'client', `next${dev ? '-dev' : ''}`) + dev && !isServer && path.join(__dirname, '..', 'client', 'webpack-hot-middleware-client'), + dev && !isServer && path.join(__dirname, '..', 'client', 'on-demand-entries-client'), + require.resolve(`../client/next${dev ? '-dev' : ''}`) ].filter(Boolean) } : {} @@ -103,17 +98,17 @@ export default async function getBaseWebpackConfig (dir, {dev = false, isServer resolve: { extensions: ['.js', '.jsx', '.json'], modules: [ - nextNodeModulesDir, + NEXT_PROJECT_ROOT_NODE_MODULES, 'node_modules', ...nodePathList // Support for NODE_PATH environment variable ], alias: { - next: nextModuleDir + next: NEXT_PROJECT_ROOT } }, resolveLoader: { modules: [ - nextNodeModulesDir, + NEXT_PROJECT_ROOT_NODE_MODULES, 'node_modules', path.join(__dirname, 'loaders'), ...nodePathList // Support for NODE_PATH environment variable @@ -126,7 +121,7 @@ export default async function getBaseWebpackConfig (dir, {dev = false, isServer loader: 'hot-self-accept-loader', include: [ path.join(dir, 'pages'), - nextPagesDir + DEFAULT_PAGES_DIR ], options: { extensions: /\.(js|jsx)$/ diff --git a/lib/constants.js b/lib/constants.js index c11392b2306bb..59657ac7c0cc7 100644 --- a/lib/constants.js +++ b/lib/constants.js @@ -1,3 +1,4 @@ +import {join} from 'path' export const PHASE_EXPORT = 'phase-export' export const PHASE_PRODUCTION_BUILD = 'phase-production-build' export const PHASE_PRODUCTION_SERVER = 'phase-production-server' @@ -14,3 +15,6 @@ export const BLOCKED_PAGES = [ ] export const IS_BUNDLED_PAGE = /^bundles[/\\]pages.*\.js$/ export const MATCH_ROUTE_NAME = /^bundles[/\\]pages[/\\](.*)\.js$/ +export const NEXT_PROJECT_ROOT = join(__dirname, '..', '..') +export const NEXT_PROJECT_ROOT_NODE_MODULES = join(NEXT_PROJECT_ROOT, 'node_modules') +export const DEFAULT_PAGES_DIR = join(NEXT_PROJECT_ROOT, 'dist', 'pages') From 3aabdfac2b2b3038aca30c0e938e152f9435ff71 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Sat, 9 Jun 2018 17:56:49 +0200 Subject: [PATCH 07/16] Remove comment marking a block --- build/webpack.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/build/webpack.js b/build/webpack.js index 058978a402d92..ba15465a45850 100644 --- a/build/webpack.js +++ b/build/webpack.js @@ -202,7 +202,6 @@ export default async function getBaseWebpackConfig (dir, {dev = false, isServer return true } - // commons // If there are one or two pages, only move modules to common if they are // used in all of the pages. Otherwise, move modules used in at-least // 1/2 of the total pages into commons. @@ -210,7 +209,6 @@ export default async function getBaseWebpackConfig (dir, {dev = false, isServer return count >= totalPages } return count >= totalPages * 0.5 - // commons end } }), // We use a manifest file in development to speed up HMR From 91ac2235918bd8d16317fe62b8df36ef0fd6b976 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Sat, 9 Jun 2018 22:58:40 +0200 Subject: [PATCH 08/16] Pass pages directory to hot-self-accept loader. Breaking change for next-typescript. --- build/loaders/hot-self-accept-loader.js | 33 +++++--- build/webpack.js | 20 +++-- flow-typed/npm/loader-utils_vx.x.x.js | 102 ++++++++++++++++++++++++ package.json | 2 +- 4 files changed, 136 insertions(+), 21 deletions(-) create mode 100644 flow-typed/npm/loader-utils_vx.x.x.js diff --git a/build/loaders/hot-self-accept-loader.js b/build/loaders/hot-self-accept-loader.js index 76a658650afb0..4609d122158e6 100644 --- a/build/loaders/hot-self-accept-loader.js +++ b/build/loaders/hot-self-accept-loader.js @@ -1,11 +1,17 @@ -import { resolve, relative } from 'path' +// @flow +import { relative } from 'path' import loaderUtils from 'loader-utils' -module.exports = function (content, sourceMap) { +type Options = { + extensions: RegExp, + include: Array +} + +module.exports = function (content: string, sourceMap: any) { this.cacheable() - const options = loaderUtils.getOptions(this) - const route = getRoute(this, options) + const options: Options = loaderUtils.getOptions(this) + const route = getRoute(this.resourcePath, options) // Webpack has a built in system to prevent default from colliding, giving it a random letter per export. // We can safely check if Component is undefined since all other pages imported into the entrypoint don't have __webpack_exports__.default @@ -30,18 +36,21 @@ module.exports = function (content, sourceMap) { `, sourceMap) } -const nextPagesDir = resolve(__dirname, '..', '..', '..', 'pages') - -function getRoute (loaderContext, options) { - const pagesDir = resolve(loaderContext.options.context, 'pages') - const { resourcePath } = loaderContext - const dir = [pagesDir, nextPagesDir] - .find((d) => resourcePath.indexOf(d) === 0) - +function getRoute (resourcePath: string, options: Options) { if (!options.extensions) { throw new Error('extensions is not provided to hot-self-accept-loader. Please upgrade all next-plugins to the latest version.') } + if (!options.include) { + throw new Error('include option is not provided to hot-self-accept-loader. Please upgrade all next-plugins to the latest version.') + } + + const dir = options.include.find((d) => resourcePath.indexOf(d) === 0) + + if (!dir) { + throw new Error(`'hot-self-accept-loader' was called on a file that isn't a page.`) + } + const path = relative(dir, resourcePath).replace(options.extensions, '.js') return '/' + path.replace(/((^|\/)index)?\.js$/, '') } diff --git a/build/webpack.js b/build/webpack.js index ba15465a45850..2eb4e15809fe3 100644 --- a/build/webpack.js +++ b/build/webpack.js @@ -53,6 +53,16 @@ export default async function getBaseWebpackConfig (dir, {dev = false, isServer babel: { loader: 'next-babel-loader', options: {dev, isServer} + }, + selfAccept: { + loader: 'hot-self-accept-loader', + options: { + include: [ + path.join(dir, 'pages'), + DEFAULT_PAGES_DIR + ], + extensions: /\.(js|jsx)$/ + } } } @@ -118,14 +128,8 @@ export default async function getBaseWebpackConfig (dir, {dev = false, isServer rules: [ dev && !isServer && { test: /\.(js|jsx)$/, - loader: 'hot-self-accept-loader', - include: [ - path.join(dir, 'pages'), - DEFAULT_PAGES_DIR - ], - options: { - extensions: /\.(js|jsx)$/ - } + include: defaultLoaders.selfAccept.include, + use: defaultLoaders.selfAccept }, { test: /\.(js|jsx)$/, diff --git a/flow-typed/npm/loader-utils_vx.x.x.js b/flow-typed/npm/loader-utils_vx.x.x.js new file mode 100644 index 0000000000000..617e83d2db327 --- /dev/null +++ b/flow-typed/npm/loader-utils_vx.x.x.js @@ -0,0 +1,102 @@ +// flow-typed signature: fbec9bc08efb50bade7bd6c2bab84e41 +// flow-typed version: <>/loader-utils_v1.1.0/flow_v0.73.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'loader-utils' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'loader-utils' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'loader-utils/lib/getCurrentRequest' { + declare module.exports: any; +} + +declare module 'loader-utils/lib/getHashDigest' { + declare module.exports: any; +} + +declare module 'loader-utils/lib/getOptions' { + declare module.exports: any; +} + +declare module 'loader-utils/lib/getRemainingRequest' { + declare module.exports: any; +} + +declare module 'loader-utils/lib/index' { + declare module.exports: any; +} + +declare module 'loader-utils/lib/interpolateName' { + declare module.exports: any; +} + +declare module 'loader-utils/lib/isUrlRequest' { + declare module.exports: any; +} + +declare module 'loader-utils/lib/parseQuery' { + declare module.exports: any; +} + +declare module 'loader-utils/lib/parseString' { + declare module.exports: any; +} + +declare module 'loader-utils/lib/stringifyRequest' { + declare module.exports: any; +} + +declare module 'loader-utils/lib/urlToRequest' { + declare module.exports: any; +} + +// Filename aliases +declare module 'loader-utils/lib/getCurrentRequest.js' { + declare module.exports: $Exports<'loader-utils/lib/getCurrentRequest'>; +} +declare module 'loader-utils/lib/getHashDigest.js' { + declare module.exports: $Exports<'loader-utils/lib/getHashDigest'>; +} +declare module 'loader-utils/lib/getOptions.js' { + declare module.exports: $Exports<'loader-utils/lib/getOptions'>; +} +declare module 'loader-utils/lib/getRemainingRequest.js' { + declare module.exports: $Exports<'loader-utils/lib/getRemainingRequest'>; +} +declare module 'loader-utils/lib/index.js' { + declare module.exports: $Exports<'loader-utils/lib/index'>; +} +declare module 'loader-utils/lib/interpolateName.js' { + declare module.exports: $Exports<'loader-utils/lib/interpolateName'>; +} +declare module 'loader-utils/lib/isUrlRequest.js' { + declare module.exports: $Exports<'loader-utils/lib/isUrlRequest'>; +} +declare module 'loader-utils/lib/parseQuery.js' { + declare module.exports: $Exports<'loader-utils/lib/parseQuery'>; +} +declare module 'loader-utils/lib/parseString.js' { + declare module.exports: $Exports<'loader-utils/lib/parseString'>; +} +declare module 'loader-utils/lib/stringifyRequest.js' { + declare module.exports: $Exports<'loader-utils/lib/stringifyRequest'>; +} +declare module 'loader-utils/lib/urlToRequest.js' { + declare module.exports: $Exports<'loader-utils/lib/urlToRequest'>; +} diff --git a/package.json b/package.json index 3509039075d4f..da8c63973121f 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "test": "cross-env npm run testall || npm run testall", "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' 'test/**/*.js'", + "lint": "standard 'bin/*' 'client/**/*.js' 'examples/**/*.js' 'lib/**/*.js' 'pages/**/*.js' 'server/**/*.js' 'build/**/*.js' 'test/**/*.js'", "prepublish": "npm run release", "precommit": "lint-staged" }, From c10588b3f1aa73d322fcab59f96f7d8c2a68ccb7 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Sat, 9 Jun 2018 23:01:44 +0200 Subject: [PATCH 09/16] Rename selfAccept to hotSelfAccept --- build/webpack.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build/webpack.js b/build/webpack.js index 2eb4e15809fe3..c8be37d7fbb8f 100644 --- a/build/webpack.js +++ b/build/webpack.js @@ -54,7 +54,7 @@ export default async function getBaseWebpackConfig (dir, {dev = false, isServer loader: 'next-babel-loader', options: {dev, isServer} }, - selfAccept: { + hotSelfAccept: { loader: 'hot-self-accept-loader', options: { include: [ @@ -128,8 +128,8 @@ export default async function getBaseWebpackConfig (dir, {dev = false, isServer rules: [ dev && !isServer && { test: /\.(js|jsx)$/, - include: defaultLoaders.selfAccept.include, - use: defaultLoaders.selfAccept + include: defaultLoaders.hotSelfAccept.include, + use: defaultLoaders.hotSelfAccept }, { test: /\.(js|jsx)$/, From 37a39afdcd1a3177b436701bb007c2f0040bbf5c Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Sat, 9 Jun 2018 23:18:40 +0200 Subject: [PATCH 10/16] Document `defaultLoaders` --- readme.md | 51 ++++++++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/readme.md b/readme.md index f975ac3f1b2ba..acc9c33735e52 100644 --- a/readme.md +++ b/readme.md @@ -1235,29 +1235,6 @@ module.exports = {

-In order to extend our usage of `webpack`, you can define a function that extends its config via `next.config.js`. - -```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, { buildId, dev, isServer, defaultLoaders }) => { - // Perform customizations to webpack config - - // Important: return the modified config - return config - }, - webpackDevMiddleware: config => { - // Perform customizations to webpack dev middleware config - - // Important: return the modified config - return config - } -} -``` - Some commonly asked for features are available as modules: - [@zeit/next-css](https://github.com/zeit/next-plugins/tree/master/packages/next-css) @@ -1282,6 +1259,34 @@ module.exports = withTypescript(withSass({ })) ``` +In order to extend our usage of `webpack`, you can define a function that extends its config via `next.config.js`. + +```js +// next.config.js is not transformed by Babel. So you can only use javascript features supported by your version of Node.js. + +module.exports = { + webpack: (config, { buildId, dev, isServer, defaultLoaders }) => { + // Perform customizations to webpack config + // Important: return the modified config + return config + }, + webpackDevMiddleware: config => { + // Perform customizations to webpack dev middleware config + // Important: return the modified config + return config + } +} +``` + +The second argument to `webpack` is an object containing properties useful when customing the WebPack configuration: + +- `buildId` - `String` the build id used as a unique identifier between builds +- `dev` - `Boolean` shows if the compilation is done in development mode +- `isServer` - `Boolean` shows if the resulting configuration will be used for server side (`true`), or client size compilation (`false`). +- `defaultLoaders` - `Object` Holds loaders Next.js uses internally, so that you can use them in custom configuration + - `babel` - `Object` the `babel-loader` configuration for Next.js. + - `hotSelfAccept` - `Object` the `hot-self-accept-loader` configuration. This loader should only be used for advanced use cases. For example [`@zeit/next-typescript`](https://github.com/zeit/next-plugins/tree/master/packages/next-typescript) adds it for top-level typescript pages. + ### Customizing babel config From 45af1430a03694c0619ccbfbca281644add170fe Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Sun, 10 Jun 2018 00:12:22 +0200 Subject: [PATCH 11/16] Read from loader options --- build/webpack.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/webpack.js b/build/webpack.js index c8be37d7fbb8f..6a17e6f7c6306 100644 --- a/build/webpack.js +++ b/build/webpack.js @@ -128,7 +128,7 @@ export default async function getBaseWebpackConfig (dir, {dev = false, isServer rules: [ dev && !isServer && { test: /\.(js|jsx)$/, - include: defaultLoaders.hotSelfAccept.include, + include: defaultLoaders.hotSelfAccept.options.include, use: defaultLoaders.hotSelfAccept }, { From 9d6b616549c6fb9db764c038087b156a970719ca Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Sun, 10 Jun 2018 13:00:00 +0200 Subject: [PATCH 12/16] hot-self-accept for internal pages never worked --- build/webpack.js | 11 +++++------ lib/constants.js | 3 ++- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/build/webpack.js b/build/webpack.js index 6a17e6f7c6306..5e188cea33ac2 100644 --- a/build/webpack.js +++ b/build/webpack.js @@ -12,7 +12,7 @@ import DynamicChunksPlugin from './plugins/dynamic-chunks-plugin' import UnlinkFilePlugin from './plugins/unlink-file-plugin' import PagesManifestPlugin from './plugins/pages-manifest-plugin' import BuildManifestPlugin from './plugins/build-manifest-plugin' -import {SERVER_DIRECTORY, NEXT_PROJECT_ROOT, NEXT_PROJECT_ROOT_NODE_MODULES, DEFAULT_PAGES_DIR} from '../lib/constants' +import {SERVER_DIRECTORY, NEXT_PROJECT_ROOT, NEXT_PROJECT_ROOT_NODE_MODULES, NEXT_PROJECT_ROOT_DIST, DEFAULT_PAGES_DIR} from '../lib/constants' function externalsConfig (dir, isServer) { const externals = [] @@ -58,8 +58,7 @@ export default async function getBaseWebpackConfig (dir, {dev = false, isServer loader: 'hot-self-accept-loader', options: { include: [ - path.join(dir, 'pages'), - DEFAULT_PAGES_DIR + path.join(dir, 'pages') ], extensions: /\.(js|jsx)$/ } @@ -75,9 +74,9 @@ export default async function getBaseWebpackConfig (dir, {dev = false, isServer const totalPages = Object.keys(pagesEntries).length const clientEntries = !isServer ? { 'main.js': [ - dev && !isServer && path.join(__dirname, '..', 'client', 'webpack-hot-middleware-client'), - dev && !isServer && path.join(__dirname, '..', 'client', 'on-demand-entries-client'), - require.resolve(`../client/next${dev ? '-dev' : ''}`) + dev && !isServer && path.join(NEXT_PROJECT_ROOT_DIST, 'client', 'webpack-hot-middleware-client'), + dev && !isServer && path.join(NEXT_PROJECT_ROOT_DIST, 'client', 'on-demand-entries-client'), + path.join(NEXT_PROJECT_ROOT_DIST, 'client', (dev ? `next-dev` : 'next')) ].filter(Boolean) } : {} diff --git a/lib/constants.js b/lib/constants.js index 59657ac7c0cc7..2a16f9f4cb7eb 100644 --- a/lib/constants.js +++ b/lib/constants.js @@ -16,5 +16,6 @@ export const BLOCKED_PAGES = [ export const IS_BUNDLED_PAGE = /^bundles[/\\]pages.*\.js$/ export const MATCH_ROUTE_NAME = /^bundles[/\\]pages[/\\](.*)\.js$/ export const NEXT_PROJECT_ROOT = join(__dirname, '..', '..') +export const NEXT_PROJECT_ROOT_DIST = join(NEXT_PROJECT_ROOT, 'dist') export const NEXT_PROJECT_ROOT_NODE_MODULES = join(NEXT_PROJECT_ROOT, 'node_modules') -export const DEFAULT_PAGES_DIR = join(NEXT_PROJECT_ROOT, 'dist', 'pages') +export const DEFAULT_PAGES_DIR = join(NEXT_PROJECT_ROOT_DIST, 'pages') From 6c7803f558f852a4afd73dd1d16f4cd620a032fa Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Thu, 14 Jun 2018 16:01:00 +0200 Subject: [PATCH 13/16] Use exact type --- build/loaders/hot-self-accept-loader.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/loaders/hot-self-accept-loader.js b/build/loaders/hot-self-accept-loader.js index 4609d122158e6..db095819d9fac 100644 --- a/build/loaders/hot-self-accept-loader.js +++ b/build/loaders/hot-self-accept-loader.js @@ -2,10 +2,10 @@ import { relative } from 'path' import loaderUtils from 'loader-utils' -type Options = { +type Options = {| extensions: RegExp, include: Array -} +|} module.exports = function (content: string, sourceMap: any) { this.cacheable() From e1b46ec4c6763739841fe913e302e9ba77fadc4e Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Thu, 14 Jun 2018 16:06:40 +0200 Subject: [PATCH 14/16] Rename regex constants --- build/plugins/pages-manifest-plugin.js | 4 ++-- build/plugins/pages-plugin.js | 8 ++++---- build/plugins/unlink-file-plugin.js | 4 ++-- lib/constants.js | 4 ++-- server/hot-reloader.js | 6 +++--- server/on-demand-entry-handler.js | 6 +++--- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/build/plugins/pages-manifest-plugin.js b/build/plugins/pages-manifest-plugin.js index 54f1a81593058..0304f6704c52e 100644 --- a/build/plugins/pages-manifest-plugin.js +++ b/build/plugins/pages-manifest-plugin.js @@ -1,6 +1,6 @@ // @flow import { RawSource } from 'webpack-sources' -import {PAGES_MANIFEST, MATCH_ROUTE_NAME} from '../../lib/constants' +import {PAGES_MANIFEST, ROUTE_NAME_REGEX} from '../../lib/constants' // This plugin creates a pages-manifest.json from page entrypoints. // This is used for mapping paths like `/` to `.next/dist/bundles/pages/index.js` when doing SSR @@ -12,7 +12,7 @@ export default class PagesManifestPlugin { const pages = {} for (const entry of entries) { - const result = MATCH_ROUTE_NAME.exec(entry.name) + const result = ROUTE_NAME_REGEX.exec(entry.name) if (!result) { continue } diff --git a/build/plugins/pages-plugin.js b/build/plugins/pages-plugin.js index 4b5548e273fea..f645341a9fffc 100644 --- a/build/plugins/pages-plugin.js +++ b/build/plugins/pages-plugin.js @@ -1,17 +1,17 @@ import { ConcatSource } from 'webpack-sources' import { - IS_BUNDLED_PAGE, - MATCH_ROUTE_NAME + IS_BUNDLED_PAGE_REGEX, + ROUTE_NAME_REGEX } from '../../lib/constants' class PageChunkTemplatePlugin { apply (chunkTemplate) { chunkTemplate.plugin('render', function (modules, chunk) { - if (!IS_BUNDLED_PAGE.test(chunk.name)) { + if (!IS_BUNDLED_PAGE_REGEX.test(chunk.name)) { return modules } - let routeName = MATCH_ROUTE_NAME.exec(chunk.name)[1] + let routeName = ROUTE_NAME_REGEX.exec(chunk.name)[1] // We need to convert \ into / when we are in windows // to get the proper route name diff --git a/build/plugins/unlink-file-plugin.js b/build/plugins/unlink-file-plugin.js index 8497a924b3c50..475e448d5e097 100644 --- a/build/plugins/unlink-file-plugin.js +++ b/build/plugins/unlink-file-plugin.js @@ -1,7 +1,7 @@ import { join } from 'path' import promisify from '../../lib/promisify' import fs from 'fs' -import { IS_BUNDLED_PAGE } from '../../lib/constants' +import { IS_BUNDLED_PAGE_REGEX } from '../../lib/constants' const unlink = promisify(fs.unlink) @@ -13,7 +13,7 @@ export default class UnlinkFilePlugin { apply (compiler) { compiler.plugin('after-emit', (compilation, callback) => { const removed = Object.keys(this.prevAssets) - .filter((a) => IS_BUNDLED_PAGE.test(a) && !compilation.assets[a]) + .filter((a) => IS_BUNDLED_PAGE_REGEX.test(a) && !compilation.assets[a]) this.prevAssets = compilation.assets diff --git a/lib/constants.js b/lib/constants.js index 2a16f9f4cb7eb..cd73adc2f9d5e 100644 --- a/lib/constants.js +++ b/lib/constants.js @@ -13,8 +13,8 @@ export const BLOCKED_PAGES = [ '/_app', '/_error' ] -export const IS_BUNDLED_PAGE = /^bundles[/\\]pages.*\.js$/ -export const MATCH_ROUTE_NAME = /^bundles[/\\]pages[/\\](.*)\.js$/ +export const IS_BUNDLED_PAGE_REGEX = /^bundles[/\\]pages.*\.js$/ +export const ROUTE_NAME_REGEX = /^bundles[/\\]pages[/\\](.*)\.js$/ export const NEXT_PROJECT_ROOT = join(__dirname, '..', '..') export const NEXT_PROJECT_ROOT_DIST = join(NEXT_PROJECT_ROOT, 'dist') export const NEXT_PROJECT_ROOT_NODE_MODULES = join(NEXT_PROJECT_ROOT, 'node_modules') diff --git a/server/hot-reloader.js b/server/hot-reloader.js index a9a0ef221e85c..44a4869c16671 100644 --- a/server/hot-reloader.js +++ b/server/hot-reloader.js @@ -9,7 +9,7 @@ import UUID from 'uuid' import { addCorsSupport } from './utils' -import {IS_BUNDLED_PAGE} from '../lib/constants' +import {IS_BUNDLED_PAGE_REGEX} from '../lib/constants' export default class HotReloader { constructor (dir, { quiet, config } = {}) { @@ -145,7 +145,7 @@ export default class HotReloader { const chunkNames = new Set( compilation.chunks .map((c) => c.name) - .filter(name => IS_BUNDLED_PAGE.test(name)) + .filter(name => IS_BUNDLED_PAGE_REGEX.test(name)) ) const failedChunkNames = new Set(compilation.errors @@ -157,7 +157,7 @@ export default class HotReloader { const chunkHashes = new Map( compilation.chunks - .filter(c => IS_BUNDLED_PAGE.test(c.name)) + .filter(c => IS_BUNDLED_PAGE_REGEX.test(c.name)) .map((c) => [c.name, c.hash]) ) diff --git a/server/on-demand-entry-handler.js b/server/on-demand-entry-handler.js index 1ce1d6e4ab02c..0ca994c752dda 100644 --- a/server/on-demand-entry-handler.js +++ b/server/on-demand-entry-handler.js @@ -7,7 +7,7 @@ import promisify from '../lib/promisify' import globModule from 'glob' import {normalizePagePath, pageNotFoundError} from './require' import {createEntry} from '../build/webpack/utils' -import { MATCH_ROUTE_NAME, IS_BUNDLED_PAGE } from '../lib/constants' +import { ROUTE_NAME_REGEX, IS_BUNDLED_PAGE_REGEX } from '../lib/constants' const ADDED = Symbol('added') const BUILDING = Symbol('building') @@ -63,7 +63,7 @@ export default function onDemandEntryHandler (devMiddleware, compilers, { if (!hasNoModuleFoundError) return false // The page itself is missing. So this is a failed page. - if (IS_BUNDLED_PAGE.test(e.module.name)) return true + if (IS_BUNDLED_PAGE_REGEX.test(e.module.name)) return true // No dependencies means this is a top level page. // So this is a failed page. @@ -72,7 +72,7 @@ export default function onDemandEntryHandler (devMiddleware, compilers, { .map(e => e.module.chunks) .reduce((a, b) => [...a, ...b], []) .map(c => { - const pageName = MATCH_ROUTE_NAME.exec(c.name)[1] + const pageName = ROUTE_NAME_REGEX.exec(c.name)[1] return normalizePage(`/${pageName}`) }) From 14977c9a32de97e228fadd5a0f0ead57c7b93955 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Thu, 14 Jun 2018 16:11:48 +0200 Subject: [PATCH 15/16] Add example of using defaultLoaders.babel --- readme.md | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index acc9c33735e52..299fc034d5b13 100644 --- a/readme.md +++ b/readme.md @@ -1283,10 +1283,33 @@ The second argument to `webpack` is an object containing properties useful when - `buildId` - `String` the build id used as a unique identifier between builds - `dev` - `Boolean` shows if the compilation is done in development mode - `isServer` - `Boolean` shows if the resulting configuration will be used for server side (`true`), or client size compilation (`false`). -- `defaultLoaders` - `Object` Holds loaders Next.js uses internally, so that you can use them in custom configuration +- `defaultLoaders` - `Object` Holds loader objects Next.js uses internally, so that you can use them in custom configuration - `babel` - `Object` the `babel-loader` configuration for Next.js. - `hotSelfAccept` - `Object` the `hot-self-accept-loader` configuration. This loader should only be used for advanced use cases. For example [`@zeit/next-typescript`](https://github.com/zeit/next-plugins/tree/master/packages/next-typescript) adds it for top-level typescript pages. +Example usage of `defaultLoaders.babel`: + +```js +// Example next.config.js for adding a loader that depends on babel-loader +// This source was taken from the @zeit/next-mdx plugin source: +// https://github.com/zeit/next-plugins/blob/master/packages/next-mdx +module.exports = { + webpack: (config, {}) => { + config.module.rules.push({ + test: extension, + use: [ + options.defaultLoaders.babel, + { + loader: '@mdx-js/loader', + options: pluginOptions.options + } + ] + }) + + return config + } +} +``` ### Customizing babel config From f5e0fcec2d6c7ea004666f5981b6bc92cc5576c2 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Thu, 14 Jun 2018 19:29:28 +0200 Subject: [PATCH 16/16] Right value for loader example --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 70ad3f284a977..17e72c2b59144 100644 --- a/readme.md +++ b/readme.md @@ -1296,7 +1296,7 @@ Example usage of `defaultLoaders.babel`: module.exports = { webpack: (config, {}) => { config.module.rules.push({ - test: extension, + test: /\.mdx/, use: [ options.defaultLoaders.babel, {