Skip to content
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

fix(lib): use proper extension #6827

Merged
merged 10 commits into from
May 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -601,9 +602,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 @@ -616,14 +619,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