Remove buildId from dynamic import URLs (#3498)

* Use without .js for the filename.

* Modify the chunk filename to add .js via webpack

* Add import chunk's hash to the filename via webpack.

* Remove buildId from dynamic import urls.

* Make sure next-export work with dynamic imports
This commit is contained in:
Arunoda Susiripala 2017-12-28 00:29:17 +05:30 committed by Tim Neutkens
parent 46b57a6eff
commit 337fb6a9aa
9 changed files with 37 additions and 33 deletions

View file

@ -21,9 +21,9 @@ const buildImport = (args) => (template(`
eval('require.ensure = function (deps, callback) { callback(require) }')
require.ensure([], (require) => {
let m = require(SOURCE)
m.__webpackChunkName = '${args.name}.js'
m.__webpackChunkName = '${args.name}'
resolve(m);
}, 'chunks/${args.name}.js');
}, 'chunks/${args.name}');
})
:
new (require('next/dynamic').SameLoopPromise)((resolve, reject) => {
@ -40,7 +40,7 @@ const buildImport = (args) => (template(`
} catch(error) {
reject(error)
}
}, 'chunks/${args.name}.js');
}, 'chunks/${args.name}');
})
)
`))

View file

@ -1,6 +1,6 @@
import { ConcatSource } from 'webpack-sources'
const isImportChunk = /^chunks[/\\].*\.js$/
const isImportChunk = /^chunks[/\\]/
const matchChunkName = /^chunks[/\\](.*)$/
class DynamicChunkTemplatePlugin {

View file

@ -325,7 +325,7 @@ export default async function createCompiler (dir, { buildId, dev = false, quiet
path: buildDir ? join(buildDir, '.next') : join(dir, config.distDir),
filename: '[name]',
libraryTarget: 'commonjs2',
publicPath: `/_next/${buildId}/webpack/`,
publicPath: `/_next/webpack/`,
strictModuleExceptionHandling: true,
devtoolModuleFilenameTemplate ({ resourcePath }) {
const hash = createHash('sha1')
@ -336,7 +336,7 @@ export default async function createCompiler (dir, { buildId, dev = false, quiet
return `webpack:///${resourcePath}?${id}`
},
// This saves chunks with the name given via require.ensure()
chunkFilename: '[name]'
chunkFilename: '[name]-[chunkhash].js'
},
resolve: {
extensions: ['.js', '.jsx', '.json'],

View file

@ -71,12 +71,12 @@ export class Head extends Component {
getPreloadDynamicChunks () {
const { chunks, __NEXT_DATA__ } = this.context._documentProps
let { assetPrefix, buildId } = __NEXT_DATA__
return chunks.map((chunk) => (
let { assetPrefix } = __NEXT_DATA__
return chunks.filenames.map((chunk) => (
<link
key={chunk}
rel='preload'
href={`${assetPrefix}/_next/${buildId}/webpack/chunks/${chunk}`}
href={`${assetPrefix}/_next/webpack/chunks/${chunk}`}
as='script'
/>
))
@ -157,15 +157,15 @@ export class NextScript extends Component {
getDynamicChunks () {
const { chunks, __NEXT_DATA__ } = this.context._documentProps
let { assetPrefix, buildId } = __NEXT_DATA__
let { assetPrefix } = __NEXT_DATA__
return (
<Fragment>
{chunks.map((chunk) => (
{chunks.filenames.map((chunk) => (
<script
async
key={chunk}
type='text/javascript'
src={`${assetPrefix}/_next/${buildId}/webpack/chunks/${chunk}`}
src={`${assetPrefix}/_next/webpack/chunks/${chunk}`}
/>
))}
</Fragment>
@ -177,7 +177,7 @@ export class NextScript extends Component {
const { pathname, buildId, assetPrefix } = __NEXT_DATA__
const pagePathname = getPagePathname(pathname)
__NEXT_DATA__.chunks = chunks
__NEXT_DATA__.chunks = chunks.names
return <Fragment>
{staticMarkup ? null : <script nonce={this.props.nonce} dangerouslySetInnerHTML={{

View file

@ -51,10 +51,10 @@ export default async function (dir, options, configuration) {
if (existsSync(join(nextDir, 'chunks'))) {
log(' copying dynamic import chunks')
await mkdirp(join(outDir, '_next', buildId, 'webpack'))
await mkdirp(join(outDir, '_next', 'webpack'))
await cp(
join(nextDir, 'chunks'),
join(outDir, '_next', buildId, 'webpack', 'chunks')
join(outDir, '_next', 'webpack', 'chunks')
)
}

View file

@ -179,7 +179,7 @@ export default class HotReloader {
]
let webpackDevMiddlewareConfig = {
publicPath: `/_next/${this.buildId}/webpack/`,
publicPath: `/_next/webpack/`,
noInfo: true,
quiet: true,
clientLogLevel: 'warning',

View file

@ -136,21 +136,17 @@ export default class Server {
},
// This is to support, webpack dynamic imports in production.
'/_next/:buildId/webpack/chunks/:name': async (req, res, params) => {
if (!this.handleBuildId(params.buildId, res)) {
return this.send404(res)
'/_next/webpack/chunks/:name': async (req, res, params) => {
// Cache aggressively in production
if (!this.dev) {
res.setHeader('Cache-Control', 'max-age=31536000, immutable')
}
const p = join(this.dir, this.dist, 'chunks', params.name)
await this.serveStatic(req, res, p)
},
// This is to support, webpack dynamic import support with HMR
'/_next/:buildId/webpack/:id': async (req, res, params) => {
if (!this.handleBuildId(params.buildId, res)) {
return this.send404(res)
}
'/_next/webpack/:id': async (req, res, params) => {
const p = join(this.dir, this.dist, 'chunks', params.id)
await this.serveStatic(req, res, p)
},

View file

@ -1,5 +1,4 @@
import { join } from 'path'
import { existsSync } from 'fs'
import { createElement } from 'react'
import { renderToString, renderToStaticMarkup } from 'react-dom/server'
import send from 'send'
@ -10,6 +9,7 @@ import getConfig from './config'
import resolvePath from './resolve'
import { Router } from '../lib/router'
import { loadGetInitialProps } from '../lib/utils'
import { getAvailableChunks } from './utils'
import Head, { defaultHead } from '../lib/head'
import App from '../lib/app'
import ErrorDebug from '../lib/error-debug'
@ -246,15 +246,22 @@ async function ensurePage (page, { dir, hotReloader }) {
function loadChunks ({ dev, dir, dist, availableChunks }) {
const flushedChunks = flushChunks()
const validChunks = []
const response = {
names: [],
filenames: []
}
if (dev) {
availableChunks = getAvailableChunks(dir, dist)
}
for (var chunk of flushedChunks) {
const filename = join(dir, dist, 'chunks', chunk)
const exists = dev ? existsSync(filename) : availableChunks[chunk]
if (exists) {
validChunks.push(chunk)
const filename = availableChunks[chunk]
if (filename) {
response.names.push(chunk)
response.filenames.push(filename)
}
}
return validChunks
return response
}

View file

@ -13,7 +13,8 @@ export function getAvailableChunks (dir, dist) {
chunkFiles.forEach(filename => {
if (/\.js$/.test(filename)) {
chunksMap[filename] = true
const chunkName = filename.replace(/-.*/, '')
chunksMap[chunkName] = filename
}
})