84 lines
2.0 KiB
JavaScript
84 lines
2.0 KiB
JavaScript
import * as path from 'path'
|
|
import Module from 'module'
|
|
import findUp from 'find-up'
|
|
import resolveFrom from 'resolve-from'
|
|
import importFrom from 'import-from'
|
|
|
|
export function withUserEnvironment(base, root, cb) {
|
|
const pnpPath = findUp.sync(
|
|
(dir) => {
|
|
const pnpFile = path.join(dir, '.pnp.js')
|
|
if (findUp.sync.exists(pnpFile)) {
|
|
return pnpFile
|
|
}
|
|
if (dir === root) {
|
|
return findUp.stop
|
|
}
|
|
},
|
|
{ cwd: base }
|
|
)
|
|
if (pnpPath) {
|
|
return withPnpEnvironment(pnpPath, cb)
|
|
}
|
|
return withNonPnpEnvironment(base, cb)
|
|
}
|
|
|
|
function withPnpEnvironment(pnpPath, cb) {
|
|
const basePath = path.dirname(pnpPath)
|
|
|
|
// pnp will patch `module` and `fs` to load package in pnp environment
|
|
// backup the functions which will be patched here
|
|
const originalModule = Object.create(null)
|
|
originalModule._load = Module._load
|
|
originalModule._resolveFilename = Module._resolveFilename
|
|
originalModule._findPath = Module._findPath
|
|
|
|
const pnpapi = __non_webpack_require__(pnpPath)
|
|
|
|
// get into pnp environment
|
|
pnpapi.setup()
|
|
|
|
// restore the patched function, we can not load any package after called this
|
|
const restore = () => Object.assign(Module, originalModule)
|
|
|
|
const pnpResolve = (request, from = basePath) => {
|
|
return pnpapi.resolveRequest(request, from + '/')
|
|
}
|
|
|
|
const pnpRequire = (request, from) => {
|
|
return __non_webpack_require__(pnpResolve(request, from))
|
|
}
|
|
|
|
const res = cb({ isPnP: true, resolve: pnpResolve, require: pnpRequire })
|
|
|
|
// check if it return a thenable
|
|
if (res != null && res.then) {
|
|
return res.then(
|
|
(x) => {
|
|
restore()
|
|
return x
|
|
},
|
|
(err) => {
|
|
restore()
|
|
throw err
|
|
}
|
|
)
|
|
}
|
|
|
|
restore()
|
|
|
|
return res
|
|
}
|
|
|
|
function withNonPnpEnvironment(base, cb) {
|
|
return cb({
|
|
isPnP: false,
|
|
require(request, from = base) {
|
|
return importFrom(from, request)
|
|
},
|
|
resolve(request, from = base) {
|
|
return resolveFrom(from, request)
|
|
},
|
|
})
|
|
}
|