mirror of
https://github.com/terribleplan/next.js.git
synced 2024-01-19 02:48:18 +00:00
Use deterministic names for dynamic import (#2788)
* Always use the same name for the same dynamic import. * Add unit tests for the modulePath generation. * Allow tests to run correctly on Windows. * Make the chunk name a bit pretty. * Fix tests to run on Windows.
This commit is contained in:
parent
ed0c144af9
commit
68738d1c90
|
@ -2,7 +2,8 @@
|
||||||
// We've added support for SSR with this version
|
// We've added support for SSR with this version
|
||||||
import template from 'babel-template'
|
import template from 'babel-template'
|
||||||
import syntax from 'babel-plugin-syntax-dynamic-import'
|
import syntax from 'babel-plugin-syntax-dynamic-import'
|
||||||
import UUID from 'uuid'
|
import { dirname, resolve, sep } from 'path'
|
||||||
|
import Crypto from 'crypto'
|
||||||
|
|
||||||
const TYPE_IMPORT = 'Import'
|
const TYPE_IMPORT = 'Import'
|
||||||
|
|
||||||
|
@ -37,14 +38,33 @@ const buildImport = (args) => (template(`
|
||||||
)
|
)
|
||||||
`))
|
`))
|
||||||
|
|
||||||
|
export function getModulePath (sourceFilename, moduleName) {
|
||||||
|
// resolve only if it's a local module
|
||||||
|
const modulePath = (moduleName[0] === '.')
|
||||||
|
? resolve(dirname(sourceFilename), moduleName) : moduleName
|
||||||
|
|
||||||
|
const cleanedModulePath = modulePath
|
||||||
|
.replace(/(index){0,1}\.js$/, '') // remove .js, index.js
|
||||||
|
.replace(/[/\\]$/, '') // remove end slash
|
||||||
|
|
||||||
|
return cleanedModulePath
|
||||||
|
}
|
||||||
|
|
||||||
export default () => ({
|
export default () => ({
|
||||||
inherits: syntax,
|
inherits: syntax,
|
||||||
|
|
||||||
visitor: {
|
visitor: {
|
||||||
CallExpression (path) {
|
CallExpression (path, state) {
|
||||||
if (path.node.callee.type === TYPE_IMPORT) {
|
if (path.node.callee.type === TYPE_IMPORT) {
|
||||||
const moduleName = path.node.arguments[0].value
|
const moduleName = path.node.arguments[0].value
|
||||||
const name = `${moduleName.replace(/[^\w]/g, '-')}-${UUID.v4()}`
|
const sourceFilename = state.file.opts.filename
|
||||||
|
|
||||||
|
const modulePath = getModulePath(sourceFilename, moduleName)
|
||||||
|
const modulePathHash = Crypto.createHash('md5').update(modulePath).digest('hex')
|
||||||
|
|
||||||
|
const relativeModulePath = modulePath.replace(`${process.cwd()}${sep}`, '')
|
||||||
|
const name = `${relativeModulePath.replace(/[^\w]/g, '-')}-${modulePathHash}`
|
||||||
|
|
||||||
const newImport = buildImport({
|
const newImport = buildImport({
|
||||||
name
|
name
|
||||||
})({
|
})({
|
||||||
|
|
42
test/unit/handle-import-babel-plugin.test.js
Normal file
42
test/unit/handle-import-babel-plugin.test.js
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/* global describe, it, expect */
|
||||||
|
import { getModulePath } from '../../dist/server/build/babel/plugins/handle-import'
|
||||||
|
|
||||||
|
function cleanPath (mPath) {
|
||||||
|
return mPath
|
||||||
|
.replace(/\\/g, '/')
|
||||||
|
.replace(/^.*:/, '')
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('handle-import-babel-plugin', () => {
|
||||||
|
describe('getModulePath', () => {
|
||||||
|
it('should not do anything to NPM modules', () => {
|
||||||
|
const mPath = getModulePath('/abc/pages/about.js', 'cool-module')
|
||||||
|
expect(mPath).toBe('cool-module')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should not do anything to private NPM modules', () => {
|
||||||
|
const mPath = getModulePath('/abc/pages/about.js', '@zeithq/cool-module')
|
||||||
|
expect(mPath).toBe('@zeithq/cool-module')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should resolve local modules', () => {
|
||||||
|
const mPath = getModulePath('/abc/pages/about.js', '../components/hello.js')
|
||||||
|
expect(cleanPath(mPath)).toBe('/abc/components/hello')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should remove index.js', () => {
|
||||||
|
const mPath = getModulePath('/abc/pages/about.js', '../components/c1/index.js')
|
||||||
|
expect(cleanPath(mPath)).toBe('/abc/components/c1')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should remove .js', () => {
|
||||||
|
const mPath = getModulePath('/abc/pages/about.js', '../components/bb.js')
|
||||||
|
expect(cleanPath(mPath)).toBe('/abc/components/bb')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should remove end slash', () => {
|
||||||
|
const mPath = getModulePath('/abc/pages/about.js', '../components/bb/')
|
||||||
|
expect(cleanPath(mPath)).toBe('/abc/components/bb')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
Loading…
Reference in a new issue