-
-
Notifications
You must be signed in to change notification settings - Fork 88
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add "fileResolve" option for deep import resolving #142
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,7 +43,7 @@ const traceKeySorter = (a, b) => { | |
}; | ||
|
||
export default class FileSystemLoader { | ||
constructor(root, plugins) { | ||
constructor(root, plugins, fileResolve) { | ||
if (root === "/" && process.platform === "win32") { | ||
const cwdDrive = process.cwd().slice(0, 3); | ||
if (!/^[A-Z]:\\$/.test(cwdDrive)) { | ||
|
@@ -55,6 +55,7 @@ export default class FileSystemLoader { | |
} | ||
|
||
this.root = root; | ||
this.fileResolve = fileResolve; | ||
this.sources = {}; | ||
this.traces = {}; | ||
this.importNr = 0; | ||
|
@@ -65,43 +66,61 @@ export default class FileSystemLoader { | |
fetch(_newPath, relativeTo, _trace) { | ||
let newPath = _newPath.replace(/^["']|["']$/g, ""), | ||
trace = _trace || String.fromCharCode(this.importNr++); | ||
const useFileResolve = typeof this.fileResolve === "function"; | ||
return new Promise((resolve, reject) => { | ||
let relativeDir = path.dirname(relativeTo), | ||
rootRelativePath = path.resolve(relativeDir, newPath), | ||
fileRelativePath = path.resolve( | ||
path.resolve(this.root, relativeDir), | ||
newPath | ||
); | ||
(useFileResolve | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's rewrite this using async/await. I'm thinking of rewriting all the promises into async/await in the future |
||
? this.fileResolve(newPath, relativeTo) | ||
: Promise.resolve() | ||
).then((fileResolvedPath) => { | ||
if (fileResolvedPath && !path.isAbsolute(fileResolvedPath)) { | ||
reject( | ||
'The returned path from the "fileResolve" option must be absolute.' | ||
); | ||
} | ||
let relativeDir = path.dirname(relativeTo), | ||
madyankin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
rootRelativePath = | ||
fileResolvedPath || path.resolve(relativeDir, newPath), | ||
fileRelativePath = | ||
fileResolvedPath || | ||
path.resolve( | ||
path.resolve(this.root, relativeDir), | ||
newPath | ||
); | ||
|
||
// if the path is not relative or absolute, try to resolve it in node_modules | ||
if (newPath[0] !== "." && !path.isAbsolute(newPath)) { | ||
try { | ||
fileRelativePath = require.resolve(newPath); | ||
} catch (e) { | ||
// noop | ||
// if the path is not relative or absolute, try to resolve it in node_modules | ||
if ( | ||
!useFileResolve && | ||
newPath[0] !== "." && | ||
!path.isAbsolute(newPath) | ||
) { | ||
try { | ||
fileRelativePath = require.resolve(newPath); | ||
} catch (e) { | ||
// noop | ||
} | ||
} | ||
} | ||
|
||
const tokens = this.tokensByFile[fileRelativePath]; | ||
if (tokens) { | ||
return resolve(tokens); | ||
} | ||
const tokens = this.tokensByFile[fileRelativePath]; | ||
if (tokens) { | ||
return resolve(tokens); | ||
} | ||
|
||
fs.readFile(fileRelativePath, "utf-8", (err, source) => { | ||
if (err) reject(err); | ||
this.core | ||
.load( | ||
source, | ||
rootRelativePath, | ||
trace, | ||
this.fetch.bind(this) | ||
) | ||
.then(({ injectableSource, exportTokens }) => { | ||
this.sources[fileRelativePath] = injectableSource; | ||
this.traces[trace] = fileRelativePath; | ||
this.tokensByFile[fileRelativePath] = exportTokens; | ||
resolve(exportTokens); | ||
}, reject); | ||
fs.readFile(fileRelativePath, "utf-8", (err, source) => { | ||
if (err) reject(err); | ||
this.core | ||
.load( | ||
source, | ||
rootRelativePath, | ||
trace, | ||
this.fetch.bind(this) | ||
) | ||
.then(({ injectableSource, exportTokens }) => { | ||
this.sources[fileRelativePath] = injectableSource; | ||
this.traces[trace] = fileRelativePath; | ||
this.tokensByFile[fileRelativePath] = exportTokens; | ||
resolve(exportTokens); | ||
}, reject); | ||
}); | ||
}); | ||
}); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,8 +33,8 @@ function getScopedNameGenerator(opts) { | |
function getLoader(opts, plugins) { | ||
const root = typeof opts.root === "undefined" ? "/" : opts.root; | ||
return typeof opts.Loader === "function" | ||
? new opts.Loader(root, plugins) | ||
: new FileSystemLoader(root, plugins); | ||
? new opts.Loader(root, plugins, opts.fileResolve) | ||
: new FileSystemLoader(root, plugins, opts.fileResolve); | ||
} | ||
|
||
function isGlobalModule(globalModules, inputFile) { | ||
|
@@ -85,6 +85,15 @@ module.exports = (opts = {}) => { | |
if (resultPluginIndex === -1) { | ||
throw new Error("Plugin missing from options."); | ||
} | ||
// resolve and fileResolve can't be used together | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you for thinking about backwards compatibility. Anyway, I'd prefer to introduce a breaking change and bump the major version. So, let's remove the original |
||
if ( | ||
typeof opts.resolve === "function" && | ||
typeof opts.fileResolve == "function" | ||
) { | ||
throw new Error( | ||
'Please use either the "resolve" or the "fileResolve" option.' | ||
); | ||
} | ||
const earlierPlugins = result.processor.plugins.slice( | ||
0, | ||
resultPluginIndex | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
.deepCompose { | ||
composes: deepDeepCompose from "test-fixture-in/deepDeepCompose.css"; | ||
content: "deepCompose"; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
.deepDeepCompose { | ||
composes: title from "test-fixture-in/composes.mixins.css"; | ||
} | ||
|
||
.dotSlashRelativePath { | ||
composes: title from "./composes.mixins.css"; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 for updating the typings