Skip to content

Commit

Permalink
fix(lib): use proper extension (#6827)
Browse files Browse the repository at this point in the history
  • Loading branch information
sachinraja authored May 5, 2022
1 parent b5c3709 commit 34df307
Show file tree
Hide file tree
Showing 12 changed files with 95 additions and 29 deletions.
2 changes: 1 addition & 1 deletion docs/config/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ export default defineConfig(({ command, mode }) => {
{
"exports": {
".": {
"import": "./index.esm.js",
"import": "./index.esm.mjs",
"require": "./index.cjs.js"
}
}
Expand Down
9 changes: 5 additions & 4 deletions docs/guide/build.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ module.exports = defineConfig({
lib: {
entry: path.resolve(__dirname, 'lib/main.js'),
name: 'MyLib',
fileName: (format) => `my-lib.${format}.js`
// the proper extensions will be added
fileName: 'my-lib'
},
rollupOptions: {
// make sure to externalize deps that shouldn't be bundled
Expand Down Expand Up @@ -159,7 +160,7 @@ Running `vite build` with this config uses a Rollup preset that is oriented towa
```
$ vite build
building for production...
[write] my-lib.es.js 0.08kb, brotli: 0.07kb
[write] my-lib.es.mjs 0.08kb, brotli: 0.07kb
[write] my-lib.umd.js 0.30kb, brotli: 0.16kb
```

Expand All @@ -170,10 +171,10 @@ Recommended `package.json` for your lib:
"name": "my-lib",
"files": ["dist"],
"main": "./dist/my-lib.umd.js",
"module": "./dist/my-lib.es.js",
"module": "./dist/my-lib.es.mjs",
"exports": {
".": {
"import": "./dist/my-lib.es.js",
"import": "./dist/my-lib.es.mjs",
"require": "./dist/my-lib.umd.js"
}
}
Expand Down
4 changes: 2 additions & 2 deletions packages/create-vite/template-lit-ts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
"name": "vite-lit-ts-starter",
"private": true,
"version": "0.0.0",
"main": "dist/my-element.es.js",
"main": "dist/my-element.es.mjs",
"exports": {
".": "./dist/my-element.es.js"
".": "./dist/my-element.es.mjs"
},
"types": "types/my-element.d.ts",
"files": [
Expand Down
4 changes: 2 additions & 2 deletions packages/create-vite/template-lit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
"name": "vite-lit-starter",
"private": true,
"version": "0.0.0",
"main": "dist/my-element.es.js",
"main": "dist/my-element.es.mjs",
"exports": {
".": "./dist/my-element.es.js"
".": "./dist/my-element.es.mjs"
},
"files": [
"dist"
Expand Down
2 changes: 1 addition & 1 deletion packages/playground/lib/index.dist.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<div class="dynamic-import-message"></div>

<script type="module">
import myLib from './my-lib-custom-filename.es.js'
import myLib from './my-lib-custom-filename.es.mjs'

myLib('.es')
</script>
Expand Down
2 changes: 1 addition & 1 deletion packages/playground/lib/vite.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ module.exports = {
entry: path.resolve(__dirname, 'src/main.js'),
name: 'MyLib',
formats: ['es', 'umd', 'iife'],
fileName: (format) => `my-lib-custom-filename.${format}.js`
fileName: 'my-lib-custom-filename'
}
},
plugins: [
Expand Down
23 changes: 13 additions & 10 deletions packages/playground/resolve-config/__tests__/resolve-config.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,42 +10,45 @@ const fromTestDir = (...p: string[]) => path.resolve(testDir, ...p)
const build = (configName: string) => {
commandSync(`${viteBin} build`, { cwd: fromTestDir(configName) })
}
const getDistFile = (configName: string) => {
return fs.readFileSync(fromTestDir(`${configName}/dist/index.es.js`), 'utf8')
const getDistFile = (configName: string, extension: string) => {
return fs.readFileSync(
fromTestDir(`${configName}/dist/index.es.${extension}`),
'utf8'
)
}

if (isBuild) {
it('loads vite.config.js', () => {
build('js')
expect(getDistFile('js')).toContain('console.log(true)')
expect(getDistFile('js', 'mjs')).toContain('console.log(true)')
})
it('loads vite.config.js with package#type module', () => {
build('js-module')
expect(getDistFile('js-module')).toContain('console.log(true)')
expect(getDistFile('js-module', 'js')).toContain('console.log(true)')
})
it('loads vite.config.cjs', () => {
build('cjs')
expect(getDistFile('cjs')).toContain('console.log(true)')
expect(getDistFile('cjs', 'mjs')).toContain('console.log(true)')
})
it('loads vite.config.cjs with package#type module', () => {
build('cjs-module')
expect(getDistFile('cjs-module')).toContain('console.log(true)')
expect(getDistFile('cjs-module', 'js')).toContain('console.log(true)')
})
it('loads vite.config.mjs', () => {
build('mjs')
expect(getDistFile('mjs')).toContain('console.log(true)')
expect(getDistFile('mjs', 'mjs')).toContain('console.log(true)')
})
it('loads vite.config.mjs with package#type module', () => {
build('mjs-module')
expect(getDistFile('mjs-module')).toContain('console.log(true)')
expect(getDistFile('mjs-module', 'js')).toContain('console.log(true)')
})
it('loads vite.config.ts', () => {
build('ts')
expect(getDistFile('ts')).toContain('console.log(true)')
expect(getDistFile('ts', 'mjs')).toContain('console.log(true)')
})
it('loads vite.config.ts with package#type module', () => {
build('ts-module')
expect(getDistFile('ts-module')).toContain('console.log(true)')
expect(getDistFile('ts-module', 'js')).toContain('console.log(true)')
})
} else {
// this test doesn't support serve mode
Expand Down
2 changes: 1 addition & 1 deletion packages/playground/vue-lib/vite.config.lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default defineConfig({
entry: path.resolve(__dirname, 'src-lib/index.ts'),
name: 'MyVueLib',
formats: ['es'],
fileName: (format) => `my-vue-lib.${format}.js`
fileName: 'my-vue-lib'
},
rollupOptions: {
external: ['vue'],
Expand Down
51 changes: 48 additions & 3 deletions packages/vite/src/node/__tests__/build.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import type { LibraryFormats, LibraryOptions } from '../build'
import { resolveLibFilename } from '../build'
import { resolve } from 'path'

type FormatsToFileNames = [LibraryFormats, string][]
const baseLibOptions: LibraryOptions = {
fileName: 'my-lib',
entry: 'mylib.js'
}

describe('resolveLibFilename', () => {
test('custom filename function', () => {
const filename = resolveLibFilename(
Expand All @@ -25,7 +32,7 @@ describe('resolveLibFilename', () => {
resolve(__dirname, 'packages/name')
)

expect(filename).toBe('custom-filename.es.js')
expect(filename).toBe('custom-filename.es.mjs')
})

test('package name as filename', () => {
Expand All @@ -37,7 +44,7 @@ describe('resolveLibFilename', () => {
resolve(__dirname, 'packages/name')
)

expect(filename).toBe('mylib.es.js')
expect(filename).toBe('mylib.es.mjs')
})

test('custom filename and no package name', () => {
Expand All @@ -50,7 +57,7 @@ describe('resolveLibFilename', () => {
resolve(__dirname, 'packages/noname')
)

expect(filename).toBe('custom-filename.es.js')
expect(filename).toBe('custom-filename.es.mjs')
})

test('missing filename', () => {
Expand All @@ -64,4 +71,42 @@ describe('resolveLibFilename', () => {
)
}).toThrow()
})

test('commonjs package extensions', () => {
const formatsToFilenames: FormatsToFileNames = [
['es', 'my-lib.es.mjs'],
['umd', 'my-lib.umd.js'],
['cjs', 'my-lib.cjs.js'],
['iife', 'my-lib.iife.js']
]

for (const [format, expectedFilename] of formatsToFilenames) {
const filename = resolveLibFilename(
baseLibOptions,
format,
resolve(__dirname, 'packages/noname')
)

expect(filename).toBe(expectedFilename)
}
})

test('module package extensions', () => {
const formatsToFilenames: FormatsToFileNames = [
['es', 'my-lib.es.js'],
['umd', 'my-lib.umd.cjs'],
['cjs', 'my-lib.cjs.cjs'],
['iife', 'my-lib.iife.js']
]

for (const [format, expectedFilename] of formatsToFilenames) {
const filename = resolveLibFilename(
baseLibOptions,
format,
resolve(__dirname, 'packages/module')
)

expect(filename).toBe(expectedFilename)
}
})
})
3 changes: 3 additions & 0 deletions packages/vite/src/node/__tests__/packages/module/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"type": "module"
}
20 changes: 16 additions & 4 deletions packages/vite/src/node/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import type { DepOptimizationMetadata } from './optimizer'
import { getDepsCacheDir, findKnownImports } from './optimizer'
import { assetImportMetaUrlPlugin } from './plugins/assetImportMetaUrl'
import { loadFallbackPlugin } from './plugins/loadFallback'
import type { PackageData } from './packages'
import { watchPackageDataPlugin } from './packages'
import { ensureWatchPlugin } from './plugins/ensureWatch'

Expand Down Expand Up @@ -563,9 +564,11 @@ function prepareOutDir(
}
}

function getPkgName(root: string) {
const { name } = JSON.parse(lookupFile(root, ['package.json']) || `{}`)
function getPkgJson(root: string): PackageData['data'] {
return JSON.parse(lookupFile(root, ['package.json']) || `{}`)
}

function getPkgName(name: string) {
return name?.startsWith('@') ? name.split('/')[1] : name
}

Expand All @@ -578,14 +581,23 @@ export function resolveLibFilename(
return libOptions.fileName(format)
}

const name = libOptions.fileName || getPkgName(root)
const packageJson = getPkgJson(root)
const name = libOptions.fileName || getPkgName(packageJson.name)

if (!name)
throw new Error(
'Name in package.json is required if option "build.lib.fileName" is not provided.'
)

return `${name}.${format}.js`
let extension: string

if (packageJson?.type === 'module') {
extension = format === 'cjs' || format === 'umd' ? 'cjs' : 'js'
} else {
extension = format === 'es' ? 'mjs' : 'js'
}

return `${name}.${format}.${extension}`
}

function resolveBuildOutputs(
Expand Down
2 changes: 2 additions & 0 deletions packages/vite/src/node/packages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ export interface PackageData {
getResolvedCache: (key: string, targetWeb: boolean) => string | undefined
data: {
[field: string]: any
name: string
type: string
version: string
main: string
module: string
Expand Down

0 comments on commit 34df307

Please sign in to comment.