Skip to content

Commit d8585ee

Browse files
committed
feat(core): Default and custom 'main' module block resolution.
1 parent 7eb9005 commit d8585ee

File tree

2 files changed

+48
-3
lines changed

2 files changed

+48
-3
lines changed

packages/@css-blocks/core/src/importing/NodeJsImporter.ts

+12-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
import { ObjectDictionary } from "@opticss/util";
22

3-
import { existsSync, readFile } from "fs-extra";
3+
import { existsSync, readFile, readFileSync } from "fs-extra";
44
import * as path from "path";
55

66
import { Syntax } from "../BlockParser";
77
import { ResolvedConfiguration } from "../configuration";
88

99
import { FileIdentifier, ImportedFile, Importer } from "./Importer";
1010

11+
const DEFAULT_MAIN = "blocks/index.block.css";
12+
1113
/**
1214
* An Alias maps the starting segment of a relative import path to a
1315
* corresponding absolute path to attempt to resolve against.
@@ -53,11 +55,19 @@ export class NodeJsImporter implements Importer {
5355
return path.resolve(alias.path, importPath.substring(alias.alias.length + 1));
5456
}
5557

56-
// If no alias found, test for a node_module resolution.
58+
// If no alias found, test for a node_module resolution as a file path.
5759
try {
5860
return require.resolve(importPath, { paths: [config.rootDir] });
5961
} catch (err) {}
6062

63+
// If no alias found, test for a node_module resolution as a package name.
64+
try {
65+
const pjsonPath = require.resolve(path.join(importPath, "package.json"), { paths: [config.rootDir] });
66+
const pjson = JSON.parse(readFileSync(pjsonPath, "utf-8"));
67+
const main: string | undefined = pjson["css-blocks"] && pjson["css-blocks"].main;
68+
return path.resolve(pjsonPath, "..", main || DEFAULT_MAIN);
69+
} catch (err) { console.log(err); }
70+
6171
// If no backup alias or node_module fount, return the previously calculated
6272
// absolute path where we expect it should be.
6373
return resolvedPath;

packages/@css-blocks/core/test/importing-test.ts

+36-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ testFSImporter("FilesystemImporter", defaultImporter);
9595
testFSImporter("Default PathAliasImporter", new NodeJsImporter({}));
9696
testFSImporter("Configured PathAliasImporter", new NodeJsImporter({alias: ALIAS_FIXTURES}));
9797

98-
describe("Node Module Importer", () => {
98+
describe("Node Module Importer – Fully Qualified Paths", () => {
9999
before(function(this: IHookCallbackContext) {
100100
this.importer = new NodeJsImporter();
101101
this.config = getConfiguration(NODE_MODULE_FIXTURES);
@@ -123,6 +123,41 @@ describe("Node Module Importer", () => {
123123
});
124124
});
125125

126+
describe("Node Module Importer – Package Names", () => {
127+
before(function(this: IHookCallbackContext) {
128+
this.importer = new NodeJsImporter();
129+
this.config = getConfiguration(NODE_MODULE_FIXTURES);
130+
});
131+
it("handles un-scoped packages default package export", function() {
132+
let packageName = "package";
133+
let ident = this.importer.identifier(null, packageName, this.config);
134+
let resolvedFilename = this.importer.filesystemPath(ident, this.config);
135+
assert.equal(ident, path.join(NODE_MODULE_FIXTURES, "node_modules", packageName, "blocks", "index.block.css"));
136+
assert.equal(resolvedFilename, path.join(NODE_MODULE_FIXTURES, "node_modules", packageName, "blocks", "index.block.css"));
137+
});
138+
it("handles scoped packages default package export", function() {
139+
let packageName = "@scoped/package";
140+
let ident = this.importer.identifier(null, packageName, this.config);
141+
let resolvedFilename = this.importer.filesystemPath(ident, this.config);
142+
assert.equal(ident, path.join(NODE_MODULE_FIXTURES, "node_modules", packageName, "blocks", "index.block.css"));
143+
assert.equal(resolvedFilename, path.join(NODE_MODULE_FIXTURES, "node_modules", packageName, "blocks", "index.block.css"));
144+
});
145+
it("handles packages with a custom main block export", function() {
146+
let packageName = "@scoped/custom-main";
147+
let ident = this.importer.identifier(null, packageName, this.config);
148+
let resolvedFilename = this.importer.filesystemPath(ident, this.config);
149+
assert.equal(ident, path.join(NODE_MODULE_FIXTURES, "node_modules", packageName, "blocks", "custom.block.css"));
150+
assert.equal(resolvedFilename, path.join(NODE_MODULE_FIXTURES, "node_modules", packageName, "blocks", "custom.block.css"));
151+
});
152+
it("gracefully degrades back to relative lookup for undiscoverable modules. Is never found without extension.", function() {
153+
let packageName = "@scoped/non-existent";
154+
let ident = this.importer.identifier(null, packageName, this.config);
155+
let resolvedFilename = this.importer.filesystemPath(ident, this.config);
156+
assert.equal(ident, path.join(NODE_MODULE_FIXTURES, packageName));
157+
assert.equal(resolvedFilename, null);
158+
});
159+
});
160+
126161
describe("PathAliasImporter", () => {
127162
before(function(this: IHookCallbackContext) {
128163
let aliases = {

0 commit comments

Comments
 (0)