ec25b4742b
This adds handling for auto-detecting TypeScript being added to a project and installing the necessary dependencies instead of printing the command and requiring the user run the command. We have been testing the auto install handling for a while now with the `next lint` command and it has worked out pretty well. This also adds HMR handling for `jsconfig.json`/`tsconfig.json` in development so if the `baseURL` or `paths` configs are modified it doesn't require a dev server restart for the updates to be picked up. This also corrects our required dependencies detection as previously an incorrect `paths: []` value was being passed to `require.resolve` causing it to fail in specific situations. Closes: https://github.com/vercel/next.js/issues/36201 ### `next build` before https://user-images.githubusercontent.com/22380829/186039578-75f8c128-a13d-4e07-b5da-13bf186ee011.mp4 ### `next build` after https://user-images.githubusercontent.com/22380829/186039662-57af22a4-da5c-4ede-94ea-96541a032cca.mp4 ### `next dev` automatic setup and HMR handling https://user-images.githubusercontent.com/22380829/186039678-d78469ef-d00b-4ee6-8163-a4706394a7b4.mp4 ## Bug - [x] Related issues linked using `fixes #number` - [x] Integration tests added - [x] Errors have helpful link attached, see `contributing.md`
55 lines
1.2 KiB
TypeScript
55 lines
1.2 KiB
TypeScript
// source: https://github.com/sindresorhus/resolve-from
|
|
import fs from 'fs'
|
|
import path from 'path'
|
|
import isError from './is-error'
|
|
|
|
const Module = require('module')
|
|
|
|
export const resolveFrom = (
|
|
fromDirectory: string,
|
|
moduleId: string,
|
|
silent?: boolean
|
|
) => {
|
|
if (typeof fromDirectory !== 'string') {
|
|
throw new TypeError(
|
|
`Expected \`fromDir\` to be of type \`string\`, got \`${typeof fromDirectory}\``
|
|
)
|
|
}
|
|
|
|
if (typeof moduleId !== 'string') {
|
|
throw new TypeError(
|
|
`Expected \`moduleId\` to be of type \`string\`, got \`${typeof moduleId}\``
|
|
)
|
|
}
|
|
|
|
try {
|
|
fromDirectory = fs.realpathSync(fromDirectory)
|
|
} catch (error: unknown) {
|
|
if (isError(error) && error.code === 'ENOENT') {
|
|
fromDirectory = path.resolve(fromDirectory)
|
|
} else if (silent) {
|
|
return
|
|
} else {
|
|
throw error
|
|
}
|
|
}
|
|
|
|
const fromFile = path.join(fromDirectory, 'noop.js')
|
|
|
|
const resolveFileName = () =>
|
|
Module._resolveFilename(moduleId, {
|
|
id: fromFile,
|
|
filename: fromFile,
|
|
paths: Module._nodeModulePaths(fromDirectory),
|
|
})
|
|
|
|
if (silent) {
|
|
try {
|
|
return resolveFileName()
|
|
} catch (error) {
|
|
return
|
|
}
|
|
}
|
|
|
|
return resolveFileName()
|
|
}
|