Last active
November 11, 2020 15:17
-
-
Save wis/51a3cdce5bccdac8092290cea51e8be8 to your computer and use it in GitHub Desktop.
parcel 2 @parcel/namer-default (DefaultNamer.js) fork
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @flow strict-local | |
import type {Bundle, FilePath} from '@parcel/types'; | |
import {Namer} from '@parcel/plugin'; | |
import ThrowableDiagnostic from '@parcel/diagnostic'; | |
import assert from 'assert'; | |
import path from 'path'; | |
import nullthrows from 'nullthrows'; | |
const COMMON_NAMES = new Set(['index', 'src', 'lib']); | |
export default (new Namer({ | |
name({bundle, bundleGraph, options}) { | |
// If the bundle has an explicit file path given (e.g. by a target), use that. | |
if (bundle.filePath != null) { | |
// TODO: what about multiple assets in the same dep? | |
// e.g. input is a Vue file, output is JS + CSS | |
// which is defined as a target in package.json? | |
return bundle.filePath; | |
} | |
let bundleGroup = bundleGraph.getBundleGroupsContainingBundle(bundle)[0]; | |
let bundleGroupBundles = bundleGraph.getBundlesInBundleGroup(bundleGroup); | |
if (bundle.isEntry) { | |
let entryBundlesOfType = bundleGroupBundles.filter( | |
b => b.isEntry && b.type === bundle.type, | |
); | |
assert( | |
entryBundlesOfType.length === 1, | |
// Otherwise, we'd end up naming two bundles the same thing. | |
'Bundle group cannot have more than one entry bundle of the same type', | |
); | |
} | |
let mainBundle = nullthrows( | |
bundleGroupBundles.find(b => | |
b.getEntryAssets().some(a => a.id === bundleGroup.entryAssetId), | |
), | |
); | |
if ( | |
bundle.id === mainBundle.id && | |
bundle.isEntry && | |
bundle.target && | |
bundle.target.distEntry != null | |
) { | |
let loc = bundle.target.loc; | |
let distEntry = bundle.target.distEntry; | |
if ( | |
path.extname(bundle.target.distEntry).slice(1) !== bundle.type && | |
loc | |
) { | |
let fullName = path.relative( | |
path.dirname(loc.filePath), | |
path.join(bundle.target.distDir, distEntry), | |
); | |
let err = new ThrowableDiagnostic({ | |
diagnostic: { | |
message: `Target "${bundle.target.name}" declares an output file path of "${fullName}" which does not match the compiled bundle type "${bundle.type}".`, | |
filePath: loc.filePath, | |
codeFrame: { | |
codeHighlights: [ | |
{ | |
start: loc.start, | |
end: loc.end, | |
message: `Did you mean "${fullName.slice( | |
0, | |
-path.extname(fullName).length, | |
) + | |
'.' + | |
bundle.type}"?`, | |
}, | |
], | |
}, | |
hints: [ | |
`Try changing the file extension of "${ | |
bundle.target.name | |
}" in ${path.relative(process.cwd(), loc.filePath)}.`, | |
], | |
}, | |
}); | |
throw err; | |
} | |
return bundle.target.distEntry; | |
} | |
// Base split bundle names on the first bundle in their group. | |
// e.g. if `index.js` imports `foo.css`, the css bundle should be called | |
// `index.css`. | |
let name = nameFromContent( | |
mainBundle, | |
bundleGroup.entryAssetId, | |
options.entryRoot, | |
); | |
if (!bundle.isEntry) { | |
name += '.' + bundle.hashReference; | |
} | |
name = name + '.' + bundle.type; | |
if(bundle.target.distDir === '.') { | |
name = '.' + name; | |
} | |
return name; | |
}, | |
}): Namer); | |
function nameFromContent( | |
bundle: Bundle, | |
entryAssetId: string, | |
entryRoot: FilePath, | |
): string { | |
let entryFilePath = nullthrows( | |
bundle.getEntryAssets().find(a => a.id === entryAssetId), | |
).filePath; | |
let name = basenameWithoutExtension(entryFilePath); | |
// If this is an entry bundle, use the original relative path. | |
if (bundle.isEntry) { | |
// Match name of target entry if possible, but with a different extension. | |
if (bundle.target.distEntry != null) { | |
return basenameWithoutExtension(bundle.target.distEntry); | |
} | |
return path | |
.join(path.relative(entryRoot, path.dirname(entryFilePath)), name) | |
.replace(/\.\.(\/|\\)/g, '__$1'); | |
} else { | |
// If this is an index file or common directory name, use the parent | |
// directory name instead, which is probably more descriptive. | |
while (COMMON_NAMES.has(name)) { | |
entryFilePath = path.dirname(entryFilePath); | |
name = path.basename(entryFilePath); | |
} | |
return name; | |
} | |
} | |
function basenameWithoutExtension(file) { | |
return path.basename(file, path.extname(file)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment