Skip to content

Commit c101763

Browse files
authored
fix: work with browserify (#13)
Browserify [does not support](browserify/resolve#224) `"exports"` in a `package.json`, and nor can you use `"browser"` in `package.json` [as a hint to Browserify to look in a certain place for a file](browserify/resolve#250 (comment)). This means the output of `ipjs` is not compatible with Browserify since it expects the runtime/bundler to use the `"exports"` field to look up files paths. If Browserify finds a file path, it will then use the `"browser"` values to apply any overrides, which `ipjs` uses to direct it to the `/cjs` folder. The problem is if it can't find the file in the first place it won't use the `"browser"` map to get the overrides. Handily we're generating the `"browser"` field values from the `"exports"` values so we know we have the complete set of files that the user wants to expose to the outside world, and the paths we want people to use to access them. The change in this PR is to use the `"browser"` field values to [mimc the `"exports"` structure in a CJS-compatible directory structure](browserify/resolve#250 (comment)) as per @ljharb's suggestion. For any file that we are overriding with `"browser"` values, we create an empty file (where a resolvable file does not already exist) a the path Browserify expects it to be at, then it'll dutifully use the `"browser"` field to pull the actual file in.
1 parent 29456b9 commit c101763

File tree

7 files changed

+34
-2
lines changed

7 files changed

+34
-2
lines changed

src/package/index.js

+34-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { promises as fs } from 'fs'
1+
import { promises as fs, existsSync } from 'fs'
22
import { rollup } from 'rollup'
33
import file from './file.js'
44
import testFile from './testFile.js'
55
import path from '../path-to-url.js'
66
import { fileURLToPath } from 'url'
7-
import { join } from 'path'
7+
import { join, dirname } from 'path'
88
import rmtree from '@tgrajewski/rmtree'
99
import preserveShebangs from 'rollup-plugin-preserve-shebangs'
1010

@@ -163,6 +163,37 @@ class Package {
163163
await unlink(new URL(dist + '/cjs/_ipjsInput.js'))
164164
}
165165

166+
async stubFiles (dist, files) {
167+
await Promise.all(
168+
files.map(async (file) => {
169+
if (file === '.') {
170+
file = 'index.js'
171+
}
172+
if (file.startsWith('./')) {
173+
file = file.substring(2)
174+
}
175+
const dir = dirname(file)
176+
if (dir !== '.') {
177+
try {
178+
await mkdir(new URL(dist + '/' + dir), {
179+
recursive: true
180+
})
181+
} catch (err) {
182+
if (err.code !== 'EEXIST') {
183+
throw err
184+
}
185+
}
186+
}
187+
188+
if (existsSync(new URL(dist + '/' + file))) {
189+
return
190+
}
191+
192+
await writeFile(new URL(dist + '/' + file), '')
193+
})
194+
)
195+
}
196+
166197
async deflate (dist) {
167198
if (!(dist instanceof URL)) dist = path(dist)
168199
rmtree(fileURLToPath(dist))
@@ -210,6 +241,7 @@ class Package {
210241
json.exports = json.exports.import
211242
json.browser = json.browser.import
212243
}
244+
await this.stubFiles(dist, Object.keys(json.browser))
213245
let files = Promise.all(pending)
214246
pending.push(writeFile(new URL(dist + '/package.json'), JSON.stringify(json, null, 2)))
215247
const typeModule = {

test/fixtures/pkg-kitchensink/output-main/index.js

Whitespace-only changes.

test/fixtures/pkg-kitchensink/output-main/secondary

Whitespace-only changes.

test/fixtures/pkg-kitchensink/output-notests/index.js

Whitespace-only changes.

test/fixtures/pkg-kitchensink/output-notests/secondary

Whitespace-only changes.

test/fixtures/pkg-kitchensink/output-tests/index.js

Whitespace-only changes.

test/fixtures/pkg-kitchensink/output-tests/secondary

Whitespace-only changes.

0 commit comments

Comments
 (0)