1
0
Fork 0
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:
Arunoda Susiripala 2017-08-16 22:44:00 +05:30 committed by GitHub
parent ed0c144af9
commit 68738d1c90
2 changed files with 65 additions and 3 deletions

View file

@ -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
})({ })({

View 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')
})
})
})