mirror of
https://github.com/terribleplan/next.js.git
synced 2024-01-19 02:48:18 +00:00
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:
parent
46b57a6eff
commit
337fb6a9aa
|
@ -21,9 +21,9 @@ const buildImport = (args) => (template(`
|
||||||
eval('require.ensure = function (deps, callback) { callback(require) }')
|
eval('require.ensure = function (deps, callback) { callback(require) }')
|
||||||
require.ensure([], (require) => {
|
require.ensure([], (require) => {
|
||||||
let m = require(SOURCE)
|
let m = require(SOURCE)
|
||||||
m.__webpackChunkName = '${args.name}.js'
|
m.__webpackChunkName = '${args.name}'
|
||||||
resolve(m);
|
resolve(m);
|
||||||
}, 'chunks/${args.name}.js');
|
}, 'chunks/${args.name}');
|
||||||
})
|
})
|
||||||
:
|
:
|
||||||
new (require('next/dynamic').SameLoopPromise)((resolve, reject) => {
|
new (require('next/dynamic').SameLoopPromise)((resolve, reject) => {
|
||||||
|
@ -40,7 +40,7 @@ const buildImport = (args) => (template(`
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
reject(error)
|
reject(error)
|
||||||
}
|
}
|
||||||
}, 'chunks/${args.name}.js');
|
}, 'chunks/${args.name}');
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
`))
|
`))
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { ConcatSource } from 'webpack-sources'
|
import { ConcatSource } from 'webpack-sources'
|
||||||
|
|
||||||
const isImportChunk = /^chunks[/\\].*\.js$/
|
const isImportChunk = /^chunks[/\\]/
|
||||||
const matchChunkName = /^chunks[/\\](.*)$/
|
const matchChunkName = /^chunks[/\\](.*)$/
|
||||||
|
|
||||||
class DynamicChunkTemplatePlugin {
|
class DynamicChunkTemplatePlugin {
|
||||||
|
|
|
@ -325,7 +325,7 @@ export default async function createCompiler (dir, { buildId, dev = false, quiet
|
||||||
path: buildDir ? join(buildDir, '.next') : join(dir, config.distDir),
|
path: buildDir ? join(buildDir, '.next') : join(dir, config.distDir),
|
||||||
filename: '[name]',
|
filename: '[name]',
|
||||||
libraryTarget: 'commonjs2',
|
libraryTarget: 'commonjs2',
|
||||||
publicPath: `/_next/${buildId}/webpack/`,
|
publicPath: `/_next/webpack/`,
|
||||||
strictModuleExceptionHandling: true,
|
strictModuleExceptionHandling: true,
|
||||||
devtoolModuleFilenameTemplate ({ resourcePath }) {
|
devtoolModuleFilenameTemplate ({ resourcePath }) {
|
||||||
const hash = createHash('sha1')
|
const hash = createHash('sha1')
|
||||||
|
@ -336,7 +336,7 @@ export default async function createCompiler (dir, { buildId, dev = false, quiet
|
||||||
return `webpack:///${resourcePath}?${id}`
|
return `webpack:///${resourcePath}?${id}`
|
||||||
},
|
},
|
||||||
// This saves chunks with the name given via require.ensure()
|
// This saves chunks with the name given via require.ensure()
|
||||||
chunkFilename: '[name]'
|
chunkFilename: '[name]-[chunkhash].js'
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
extensions: ['.js', '.jsx', '.json'],
|
extensions: ['.js', '.jsx', '.json'],
|
||||||
|
|
|
@ -71,12 +71,12 @@ export class Head extends Component {
|
||||||
|
|
||||||
getPreloadDynamicChunks () {
|
getPreloadDynamicChunks () {
|
||||||
const { chunks, __NEXT_DATA__ } = this.context._documentProps
|
const { chunks, __NEXT_DATA__ } = this.context._documentProps
|
||||||
let { assetPrefix, buildId } = __NEXT_DATA__
|
let { assetPrefix } = __NEXT_DATA__
|
||||||
return chunks.map((chunk) => (
|
return chunks.filenames.map((chunk) => (
|
||||||
<link
|
<link
|
||||||
key={chunk}
|
key={chunk}
|
||||||
rel='preload'
|
rel='preload'
|
||||||
href={`${assetPrefix}/_next/${buildId}/webpack/chunks/${chunk}`}
|
href={`${assetPrefix}/_next/webpack/chunks/${chunk}`}
|
||||||
as='script'
|
as='script'
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
|
@ -157,15 +157,15 @@ export class NextScript extends Component {
|
||||||
|
|
||||||
getDynamicChunks () {
|
getDynamicChunks () {
|
||||||
const { chunks, __NEXT_DATA__ } = this.context._documentProps
|
const { chunks, __NEXT_DATA__ } = this.context._documentProps
|
||||||
let { assetPrefix, buildId } = __NEXT_DATA__
|
let { assetPrefix } = __NEXT_DATA__
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
{chunks.map((chunk) => (
|
{chunks.filenames.map((chunk) => (
|
||||||
<script
|
<script
|
||||||
async
|
async
|
||||||
key={chunk}
|
key={chunk}
|
||||||
type='text/javascript'
|
type='text/javascript'
|
||||||
src={`${assetPrefix}/_next/${buildId}/webpack/chunks/${chunk}`}
|
src={`${assetPrefix}/_next/webpack/chunks/${chunk}`}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
@ -177,7 +177,7 @@ export class NextScript extends Component {
|
||||||
const { pathname, buildId, assetPrefix } = __NEXT_DATA__
|
const { pathname, buildId, assetPrefix } = __NEXT_DATA__
|
||||||
const pagePathname = getPagePathname(pathname)
|
const pagePathname = getPagePathname(pathname)
|
||||||
|
|
||||||
__NEXT_DATA__.chunks = chunks
|
__NEXT_DATA__.chunks = chunks.names
|
||||||
|
|
||||||
return <Fragment>
|
return <Fragment>
|
||||||
{staticMarkup ? null : <script nonce={this.props.nonce} dangerouslySetInnerHTML={{
|
{staticMarkup ? null : <script nonce={this.props.nonce} dangerouslySetInnerHTML={{
|
||||||
|
|
|
@ -51,10 +51,10 @@ export default async function (dir, options, configuration) {
|
||||||
if (existsSync(join(nextDir, 'chunks'))) {
|
if (existsSync(join(nextDir, 'chunks'))) {
|
||||||
log(' copying dynamic import chunks')
|
log(' copying dynamic import chunks')
|
||||||
|
|
||||||
await mkdirp(join(outDir, '_next', buildId, 'webpack'))
|
await mkdirp(join(outDir, '_next', 'webpack'))
|
||||||
await cp(
|
await cp(
|
||||||
join(nextDir, 'chunks'),
|
join(nextDir, 'chunks'),
|
||||||
join(outDir, '_next', buildId, 'webpack', 'chunks')
|
join(outDir, '_next', 'webpack', 'chunks')
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -179,7 +179,7 @@ export default class HotReloader {
|
||||||
]
|
]
|
||||||
|
|
||||||
let webpackDevMiddlewareConfig = {
|
let webpackDevMiddlewareConfig = {
|
||||||
publicPath: `/_next/${this.buildId}/webpack/`,
|
publicPath: `/_next/webpack/`,
|
||||||
noInfo: true,
|
noInfo: true,
|
||||||
quiet: true,
|
quiet: true,
|
||||||
clientLogLevel: 'warning',
|
clientLogLevel: 'warning',
|
||||||
|
|
|
@ -136,21 +136,17 @@ export default class Server {
|
||||||
},
|
},
|
||||||
|
|
||||||
// This is to support, webpack dynamic imports in production.
|
// This is to support, webpack dynamic imports in production.
|
||||||
'/_next/:buildId/webpack/chunks/:name': async (req, res, params) => {
|
'/_next/webpack/chunks/:name': async (req, res, params) => {
|
||||||
if (!this.handleBuildId(params.buildId, res)) {
|
// Cache aggressively in production
|
||||||
return this.send404(res)
|
if (!this.dev) {
|
||||||
|
res.setHeader('Cache-Control', 'max-age=31536000, immutable')
|
||||||
}
|
}
|
||||||
|
|
||||||
const p = join(this.dir, this.dist, 'chunks', params.name)
|
const p = join(this.dir, this.dist, 'chunks', params.name)
|
||||||
await this.serveStatic(req, res, p)
|
await this.serveStatic(req, res, p)
|
||||||
},
|
},
|
||||||
|
|
||||||
// This is to support, webpack dynamic import support with HMR
|
// This is to support, webpack dynamic import support with HMR
|
||||||
'/_next/:buildId/webpack/:id': async (req, res, params) => {
|
'/_next/webpack/:id': async (req, res, params) => {
|
||||||
if (!this.handleBuildId(params.buildId, res)) {
|
|
||||||
return this.send404(res)
|
|
||||||
}
|
|
||||||
|
|
||||||
const p = join(this.dir, this.dist, 'chunks', params.id)
|
const p = join(this.dir, this.dist, 'chunks', params.id)
|
||||||
await this.serveStatic(req, res, p)
|
await this.serveStatic(req, res, p)
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { join } from 'path'
|
import { join } from 'path'
|
||||||
import { existsSync } from 'fs'
|
|
||||||
import { createElement } from 'react'
|
import { createElement } from 'react'
|
||||||
import { renderToString, renderToStaticMarkup } from 'react-dom/server'
|
import { renderToString, renderToStaticMarkup } from 'react-dom/server'
|
||||||
import send from 'send'
|
import send from 'send'
|
||||||
|
@ -10,6 +9,7 @@ import getConfig from './config'
|
||||||
import resolvePath from './resolve'
|
import resolvePath from './resolve'
|
||||||
import { Router } from '../lib/router'
|
import { Router } from '../lib/router'
|
||||||
import { loadGetInitialProps } from '../lib/utils'
|
import { loadGetInitialProps } from '../lib/utils'
|
||||||
|
import { getAvailableChunks } from './utils'
|
||||||
import Head, { defaultHead } from '../lib/head'
|
import Head, { defaultHead } from '../lib/head'
|
||||||
import App from '../lib/app'
|
import App from '../lib/app'
|
||||||
import ErrorDebug from '../lib/error-debug'
|
import ErrorDebug from '../lib/error-debug'
|
||||||
|
@ -246,15 +246,22 @@ async function ensurePage (page, { dir, hotReloader }) {
|
||||||
|
|
||||||
function loadChunks ({ dev, dir, dist, availableChunks }) {
|
function loadChunks ({ dev, dir, dist, availableChunks }) {
|
||||||
const flushedChunks = flushChunks()
|
const flushedChunks = flushChunks()
|
||||||
const validChunks = []
|
const response = {
|
||||||
|
names: [],
|
||||||
|
filenames: []
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dev) {
|
||||||
|
availableChunks = getAvailableChunks(dir, dist)
|
||||||
|
}
|
||||||
|
|
||||||
for (var chunk of flushedChunks) {
|
for (var chunk of flushedChunks) {
|
||||||
const filename = join(dir, dist, 'chunks', chunk)
|
const filename = availableChunks[chunk]
|
||||||
const exists = dev ? existsSync(filename) : availableChunks[chunk]
|
if (filename) {
|
||||||
if (exists) {
|
response.names.push(chunk)
|
||||||
validChunks.push(chunk)
|
response.filenames.push(filename)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return validChunks
|
return response
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,8 @@ export function getAvailableChunks (dir, dist) {
|
||||||
|
|
||||||
chunkFiles.forEach(filename => {
|
chunkFiles.forEach(filename => {
|
||||||
if (/\.js$/.test(filename)) {
|
if (/\.js$/.test(filename)) {
|
||||||
chunksMap[filename] = true
|
const chunkName = filename.replace(/-.*/, '')
|
||||||
|
chunksMap[chunkName] = filename
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue