Skip to content

Commit 5180e7e

Browse files
anmonteiroswannodette
authored andcommitted
CLJS-2327: module_deps.js doesn't know about browser field advanced usage
1 parent 5a5c1e7 commit 5180e7e

3 files changed

Lines changed: 133 additions & 25 deletions

File tree

src/main/cljs/cljs/module_deps.js

Lines changed: 70 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ let enhancedResolve = require('enhanced-resolve');
88

99
let target = 'CLJS_TARGET';
1010
let filename = fs.realpathSync(path.resolve(__dirname, 'JS_FILE'));
11-
let mainFields = ['module', 'main'];
11+
let mainFields = target === 'nodejs'
12+
? ['module', 'main']
13+
: ['browser', 'module', 'main'];
1214
let aliasFields = target === 'nodejs' ? [] : ['browser'];
1315

1416
// https://github.com/egoist/konan
@@ -61,7 +63,7 @@ let resolver = enhancedResolve.create({
6163
),
6264
extensions: ['.js', '.json'],
6365
mainFields: mainFields,
64-
aliasFields: aliasFields,
66+
aliasFields: target === 'nodejs' ? [] : ['browser'],
6567
moduleExtensions: ['.js', '.json']
6668
});
6769

@@ -89,21 +91,59 @@ let md = mdeps({
8991
function getPackageJsonMainEntry(pkgJson) {
9092
for (let i = 0; i < mainFields.length; i++) {
9193
let entry = mainFields[i];
92-
93-
if (pkgJson[entry] != null) {
94-
return pkgJson[entry];
94+
const entryVal = pkgJson[entry];
95+
96+
if (entryVal != null) {
97+
if (typeof entryVal === 'string') {
98+
return entryVal;
99+
} else if (typeof entryVal === 'object') {
100+
for (let j = i; j < mainFields.length; j++) {
101+
let otherEntry = mainFields[j];
102+
const otherEntryVal = pkgJson[entry];
103+
104+
if (entryVal[otherEntryVal] != null) {
105+
return entryVal[otherEntryVal]
106+
}
107+
}
108+
}
95109
}
96110
}
97111
return null;
98112
}
99113

114+
function depProvides(provides, file) {
115+
const result = provides != null ? provides.slice(0) : [];
116+
117+
let providedModule = file
118+
.substring(file.lastIndexOf('node_modules'))
119+
.replace(/\\/g, '/')
120+
.replace('node_modules/', '');
121+
122+
result.push(
123+
providedModule,
124+
providedModule.replace(/\.js(on)?$/, '')
125+
);
126+
127+
let indexReplaced = providedModule.replace(/\/index\.js(on)?$/, '');
128+
129+
if (
130+
/\/index\.js(on)?$/.test(providedModule) &&
131+
result.indexOf(indexReplaced) === -1
132+
) {
133+
result.push(indexReplaced);
134+
}
135+
136+
return result;
137+
}
138+
100139
let pkgJsons = [];
101140
let deps_files = {};
102141

103142
md.on('package', function (pkg) {
104143
// we don't want to include the package.json for users' projects
105144
if (/node_modules/.test(pkg.__dirname)) {
106145
let pkgJson = {
146+
basedir: pkg.__dirname,
107147
file: path.join(pkg.__dirname, 'package.json'),
108148
};
109149

@@ -116,6 +156,14 @@ md.on('package', function (pkg) {
116156
pkgJson.mainEntry = path.join(pkg.__dirname, pkgJsonMainEntry);
117157
}
118158

159+
// we'll need these later
160+
for (let i = 0; i < aliasFields.length; i++) {
161+
const field = aliasFields[i];
162+
if (pkg[field] != null) {
163+
pkgJson[field] = pkg[field];
164+
}
165+
}
166+
119167
pkgJsons.push(pkgJson);
120168
}
121169
});
@@ -132,6 +180,22 @@ md.on('end', function () {
132180
deps_files[pkgJson.mainEntry].provides = pkgJson.provides;
133181
}
134182

183+
for (let j = 0; j < aliasFields.length; j++) {
184+
const field = aliasFields[j];
185+
const fieldValue = pkgJson[field];
186+
187+
if (fieldValue != null && typeof fieldValue === 'object') {
188+
for (let key in fieldValue) {
189+
const replacement = path.resolve(pkgJson.basedir, fieldValue[key]);
190+
191+
if (deps_files[replacement] != null) {
192+
deps_files[replacement].provides = depProvides(deps_files[replacement].provides, path.resolve(pkgJson.basedir, key));
193+
}
194+
}
195+
}
196+
}
197+
198+
135199
deps_files[pkgJson.file] = {file: pkgJson.file};
136200
}
137201

@@ -146,25 +210,7 @@ md.on('end', function () {
146210
)
147211
) {
148212
if (dep.file.indexOf('node_modules') !== -1) {
149-
let providedModule = dep.file
150-
.substring(dep.file.lastIndexOf('node_modules'))
151-
.replace(/\\/g, '/')
152-
.replace('node_modules/', '');
153-
154-
dep.provides = dep.provides || [];
155-
dep.provides.push(
156-
providedModule,
157-
providedModule.replace(/\.js(on)?$/, '')
158-
);
159-
160-
let indexReplaced = providedModule.replace(/\/index\.js(on)?$/, '');
161-
162-
if (
163-
/\/index\.js(on)?$/.test(providedModule) &&
164-
dep.provides.indexOf(indexReplaced) === -1
165-
) {
166-
dep.provides.push(indexReplaced);
167-
}
213+
dep.provides = depProvides(dep.provides, dep.file);
168214
}
169215
}
170216

src/main/clojure/cljs/closure.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2281,7 +2281,7 @@
22812281
(index-node-modules-dir
22822282
(when env/*compiler*
22832283
(:options @env/*compiler*))))
2284-
([{:keys [verbose target]}]
2284+
([opts]
22852285
(let [module-fseq (util/module-file-seq)]
22862286
(node-file-seq->libs-spec module-fseq))))
22872287

src/test/clojure/cljs/closure_tests.clj

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,3 +277,65 @@
277277
(closure/index-node-modules ["tslib"] opts))))
278278
(test/delete-node-modules)
279279
(test/delete-out-files out)))
280+
281+
(deftest test-cljs-2327
282+
(spit (io/file "package.json") "{}")
283+
(let [opts {:npm-deps {:react "16.0.0-beta.5"
284+
:react-dom "16.0.0-beta.5"}}
285+
out (util/output-directory opts)]
286+
(test/delete-node-modules)
287+
(test/delete-out-files out)
288+
(closure/maybe-install-node-deps! opts)
289+
(let [modules (closure/index-node-modules ["react" "react-dom" "react-dom/server"] opts)]
290+
(is (true? (some (fn [module]
291+
(= module {:module-type :es6
292+
:file (.getAbsolutePath (io/file "node_modules/react/index.js"))
293+
:provides ["react"
294+
"react/index.js"
295+
"react/index"]}))
296+
modules)))
297+
(is (true? (some (fn [module]
298+
(= module {:module-type :es6
299+
:file (.getAbsolutePath (io/file "node_modules/react-dom/index.js"))
300+
:provides ["react-dom"
301+
"react-dom/index.js"
302+
"react-dom/index"]}))
303+
modules)))
304+
(is (true? (some (fn [module]
305+
(= module {:module-type :es6
306+
:file (.getAbsolutePath (io/file "node_modules/react-dom/server.browser.js"))
307+
:provides ["react-dom/server.js"
308+
"react-dom/server"
309+
"react-dom/server.browser.js"
310+
"react-dom/server.browser"]}))
311+
modules))))
312+
(test/delete-node-modules)
313+
(test/delete-out-files out)
314+
(spit (io/file "package.json") "{}")
315+
(let [opts {:npm-deps {:warning "3.0.0"}}
316+
_ (closure/maybe-install-node-deps! opts)
317+
modules (closure/index-node-modules ["warning"] opts)]
318+
(is (true? (some (fn [module]
319+
(= module {:module-type :es6
320+
:file (.getAbsolutePath (io/file "node_modules/warning/browser.js"))
321+
:provides ["warning"
322+
"warning/browser.js"
323+
"warning/browser"]}))
324+
modules))))
325+
(test/delete-node-modules)
326+
(test/delete-out-files out)
327+
(spit (io/file "package.json") "{}")
328+
(let [opts {:npm-deps {:react-dom "16.0.0-beta.5"
329+
:react "16.0.0-beta.5"}
330+
:target :nodejs}
331+
_ (closure/maybe-install-node-deps! opts)
332+
modules (closure/index-node-modules ["react-dom/server"] opts)]
333+
(is (true? (some (fn [module]
334+
(= module {:module-type :es6
335+
:file (.getAbsolutePath (io/file "node_modules/react-dom/server.js"))
336+
:provides ["react-dom/server.js"
337+
"react-dom/server"]}))
338+
modules))))
339+
(.delete (io/file "package.json"))
340+
(test/delete-node-modules)
341+
(test/delete-out-files out)))

0 commit comments

Comments
 (0)