-
-
Notifications
You must be signed in to change notification settings - Fork 379
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat/tsconfig-paths * Adding post-process resolver * fix up lockfile * bump canary * bump canary Co-authored-by: L <[email protected]>
- Loading branch information
Showing
18 changed files
with
377 additions
and
301 deletions.
There are no files selected for viewing
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
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
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
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
node_modules | ||
|
||
dist/ |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
{ | ||
"name": "@plasmohq/parcel-resolver-post", | ||
"version": "0.0.0", | ||
"description": "Plasmo Parcel Resolver Post-processing", | ||
"files": [ | ||
"dist" | ||
], | ||
"main": "dist/index.js", | ||
"scripts": { | ||
"prepublishOnly": "pnpm build", | ||
"build": "tsup src/index.ts --minify --clean", | ||
"dev": "tsup src/index.ts --watch" | ||
}, | ||
"author": "Plasmo Corp. <[email protected]>", | ||
"homepage": "https://docs.plasmo.com/", | ||
"engines": { | ||
"parcel": ">= 2.7.0" | ||
}, | ||
"license": "MIT", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/PlasmoHQ/plasmo.git" | ||
}, | ||
"devDependencies": { | ||
"@plasmo/config": "workspace:*", | ||
"@plasmo/utils": "workspace:*" | ||
}, | ||
"dependencies": { | ||
"@parcel/core": "2.7.0", | ||
"@parcel/utils": "2.7.0", | ||
"@parcel/types": "2.7.0", | ||
"@parcel/hash": "2.7.0", | ||
"@parcel/plugin": "2.7.0", | ||
"typescript": "4.8.4", | ||
"tsup": "6.3.0" | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
/** | ||
* Copyright (c) 2022 Plasmo Corp. <[email protected]> (https://www.plasmo.com) and contributors | ||
* MIT License | ||
* | ||
* Based on: https://github.com/zachbryant/parcel-resolver-tspaths | ||
* Copyright (c) 2021 Zach Bryant | ||
* MIT License | ||
*/ | ||
|
||
import { loadConfig } from "@parcel/utils" | ||
import { extname, join, resolve } from "path" | ||
import type { CompilerOptions } from "typescript" | ||
|
||
import type { ResolverProps, ResolverResult } from "./shared" | ||
import { checkWebpackSpecificImportSyntax, findModule, trimStar } from "./utils" | ||
|
||
const tsRegex = /\.tsx?$/ | ||
|
||
const relevantExtList = [ | ||
".ts", | ||
".tsx", | ||
".svelte", | ||
".vue", | ||
".json", | ||
|
||
".css", | ||
".scss", | ||
".sass", | ||
".less", | ||
|
||
".svg", | ||
|
||
".js", | ||
".jsx" | ||
] as const | ||
|
||
const relevantExtSet = new Set(relevantExtList) | ||
|
||
type TsPaths = string[] | ||
|
||
type TsPathsMap = Map<string, TsPaths> | ||
|
||
const state = { | ||
pathsMap: null as TsPathsMap, | ||
pathsMapRegex: null as [string, TsPaths, RegExp][] | ||
} | ||
|
||
export async function handleTsPath( | ||
props: ResolverProps | ||
): Promise<ResolverResult> { | ||
try { | ||
const { dependency } = props | ||
|
||
checkWebpackSpecificImportSyntax(dependency.specifier) | ||
|
||
const isTypescript = tsRegex.test(dependency.resolveFrom) | ||
|
||
if (!isTypescript) { | ||
return null | ||
} | ||
|
||
const { compilerOptions } = await getTsconfigCompilerOptions(props) | ||
if (!compilerOptions) { | ||
return null | ||
} | ||
|
||
loadTsPathsMap(compilerOptions) | ||
|
||
const result = attemptResolve(props) | ||
|
||
if (!result) { | ||
return null | ||
} | ||
|
||
return { | ||
filePath: result | ||
} | ||
} catch { | ||
return null | ||
} | ||
} | ||
|
||
/** Populate a map with any paths from tsconfig.json starting from baseUrl */ | ||
function loadTsPathsMap(compilerOptions: CompilerOptions) { | ||
if (state.pathsMap) { | ||
return | ||
} | ||
|
||
const baseUrl = compilerOptions.baseUrl || "." | ||
const tsPaths = compilerOptions.paths || {} | ||
|
||
const tsPathsMap = Object.entries(tsPaths).reduce( | ||
(output, [key, pathList]) => { | ||
output.set( | ||
key, | ||
pathList.map((p) => join(baseUrl, p)) | ||
) | ||
return output | ||
}, | ||
new Map<string, TsPaths>() | ||
) | ||
|
||
state.pathsMap = tsPathsMap | ||
state.pathsMapRegex = Array.from(tsPathsMap.entries()).map((entry) => [ | ||
...entry, | ||
new RegExp(`^${entry[0].replace("*", ".*")}$`) | ||
]) | ||
} | ||
|
||
function attemptResolve({ specifier, dependency }: ResolverProps) { | ||
const { pathsMap, pathsMapRegex } = state | ||
if (pathsMap.has(specifier)) { | ||
return attemptResolveArray( | ||
specifier, | ||
specifier, | ||
pathsMap.get(specifier), | ||
dependency.resolveFrom | ||
) | ||
} | ||
|
||
const relevantEntry = pathsMapRegex.find(([, , aliasRegex]) => | ||
aliasRegex.test(specifier) | ||
) | ||
|
||
if (!!relevantEntry) { | ||
return attemptResolveArray( | ||
specifier, | ||
relevantEntry[0], | ||
relevantEntry[1], | ||
dependency.resolveFrom | ||
) | ||
} | ||
|
||
return null | ||
} | ||
|
||
// TODO support resource loaders like 'url:@alias/my.svg' | ||
/** Attempt to resolve any path associated with the alias to a file or directory index */ | ||
function attemptResolveArray( | ||
from: string, | ||
alias: string, | ||
realPaths: TsPaths, | ||
parentFile: string | ||
) { | ||
for (const option of realPaths) { | ||
const absoluteBaseFile = resolve( | ||
from.replace(trimStar(alias), trimStar(option)) | ||
) | ||
|
||
const importExt = extname(absoluteBaseFile) | ||
|
||
if (importExt.length > 0 && relevantExtSet.has(importExt as any)) { | ||
return absoluteBaseFile | ||
} | ||
|
||
const parentExt = extname(parentFile) | ||
|
||
const checkingExts = [ | ||
parentExt, | ||
...relevantExtList.filter((ext) => ext !== parentExt) | ||
] | ||
|
||
const mod = findModule(absoluteBaseFile, checkingExts) | ||
|
||
if (mod !== null) { | ||
return mod | ||
} | ||
} | ||
return null | ||
} | ||
|
||
async function getTsconfigCompilerOptions({ | ||
options, | ||
dependency | ||
}: ResolverProps) { | ||
const result = await loadConfig( | ||
options.inputFS, | ||
dependency.resolveFrom, | ||
["tsconfig.json", "tsconfig.js"], | ||
join(process.env.PLASMO_PROJECT_DIR, "lab") | ||
) | ||
|
||
if (!result?.config?.compilerOptions) { | ||
return null | ||
} | ||
|
||
const filePath = result.files[0].filePath | ||
const compilerOptions = result?.config?.compilerOptions as CompilerOptions | ||
return { | ||
compilerOptions, | ||
filePath | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { Resolver } from "@parcel/plugin" | ||
|
||
import { handleTsPath } from "./handle-ts-path" | ||
|
||
export default new Resolver({ | ||
async resolve(props) { | ||
return (await handleTsPath(props)) || null | ||
} | ||
}) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import type { Resolver } from "@parcel/plugin" | ||
import type { ResolveResult } from "@parcel/types" | ||
|
||
export const relevantExtensionList = [ | ||
".ts", | ||
".tsx", | ||
".svelte", | ||
".vue", | ||
".json", | ||
|
||
".js", | ||
".jsx" | ||
] as const | ||
|
||
export const relevantExtensionSet = new Set(relevantExtensionList) | ||
|
||
type ResolveFx = ConstructorParameters<typeof Resolver>[0]["resolve"] | ||
|
||
export type ResolverResult = ResolveResult | ||
export type ResolverProps = Parameters<ResolveFx>[0] |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import type { ResolveResult } from "@parcel/types" | ||
import { statSync } from "fs" | ||
import { resolve } from "path" | ||
|
||
import { type ResolverResult, relevantExtensionList } from "./shared" | ||
|
||
const WEBPACK_IMPORT_REGEX = /\S+-loader\S*!\S+/g | ||
|
||
export function checkWebpackSpecificImportSyntax(specifier = "") { | ||
// Throw user friendly errors on special webpack loader syntax | ||
// ex. `imports-loader?$=jquery!./example.js` | ||
if (WEBPACK_IMPORT_REGEX.test(specifier)) { | ||
throw new Error( | ||
`The import path: ${specifier} is using webpack specific loader import syntax, which isn't supported by Parcel.` | ||
) | ||
} | ||
} | ||
|
||
export function trimStar(str: string) { | ||
return trim(str, "*") | ||
} | ||
|
||
export function trim(str: string, trim: string) { | ||
if (str.endsWith(trim)) { | ||
str = str.substring(0, str.length - trim.length) | ||
} | ||
return str | ||
} | ||
|
||
const isFile = (filePath: string) => { | ||
try { | ||
return statSync(filePath).isFile() | ||
} catch { | ||
return false | ||
} | ||
} | ||
|
||
export function findModule( | ||
absoluteBaseFile: string, | ||
checkingExts = relevantExtensionList as readonly string[] | ||
) { | ||
return checkingExts | ||
.flatMap((ext) => [ | ||
resolve(`${absoluteBaseFile}${ext}`), | ||
resolve(absoluteBaseFile, `index${ext}`) | ||
]) | ||
.find(isFile) | ||
} | ||
|
||
/** | ||
* Look for source code file (crawl index) | ||
*/ | ||
export const resolveSourceIndex = async ( | ||
absoluteBaseFile: string, | ||
checkingExts = relevantExtensionList as readonly string[], | ||
opts = {} as Partial<ResolveResult> | ||
): Promise<ResolverResult> => { | ||
const filePath = findModule(absoluteBaseFile, checkingExts) | ||
|
||
if (!filePath) { | ||
return null | ||
} | ||
|
||
return { filePath, ...opts } | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"extends": "@plasmo/config/ts/cli", | ||
"include": ["src/**/*.ts"], | ||
"exclude": ["dist", "node_modules"] | ||
} |
Oops, something went wrong.