mirror of
https://github.com/vuejs/vue-cli.git
synced 2026-04-20 11:30:43 -05:00
feat(build): support named exports when building --target lib with js/ts entry
close #1436 BREAKING CHANGE: When building a js/ts entry file with --target lib, the library now exposes a Module with both default and named exports. This means in the UMD build, the default export now needs to be accessed as `window.yourLib.default`, and in the CommonJS build as `const yourLib = require('yourLib').default`. If you don't have named exports and want to retain the previous behavior, you can configure webpack to use `output.libraryExport: 'default'` in `vue.config.js`.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
jest.setTimeout(30000)
|
||||
jest.setTimeout(40000)
|
||||
|
||||
const path = require('path')
|
||||
const portfinder = require('portfinder')
|
||||
@@ -8,6 +8,12 @@ const create = require('@vue/cli-test-utils/createTestProject')
|
||||
const launchPuppeteer = require('@vue/cli-test-utils/launchPuppeteer')
|
||||
|
||||
let server, browser, page
|
||||
|
||||
afterEach(async () => {
|
||||
await browser.close()
|
||||
server.close()
|
||||
})
|
||||
|
||||
test('build as lib', async () => {
|
||||
const project = await create('build-lib', defaultPreset)
|
||||
|
||||
@@ -45,7 +51,40 @@ test('build as lib', async () => {
|
||||
expect(h3Text).toMatch('Installed CLI Plugins')
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
await browser.close()
|
||||
server.close()
|
||||
test('build as lib (js)', async () => {
|
||||
const project = await create('build-lib-js', defaultPreset)
|
||||
await project.write('src/main.js', `
|
||||
export default { foo: 1 }
|
||||
export const bar = 2
|
||||
`)
|
||||
const { stdout } = await project.run('vue-cli-service build --target lib --name testLib src/main.js')
|
||||
expect(stdout).toMatch('Build complete.')
|
||||
|
||||
expect(project.has('dist/demo.html')).toBe(true)
|
||||
expect(project.has('dist/testLib.common.js')).toBe(true)
|
||||
expect(project.has('dist/testLib.umd.js')).toBe(true)
|
||||
expect(project.has('dist/testLib.umd.min.js')).toBe(true)
|
||||
|
||||
const port = await portfinder.getPortPromise()
|
||||
server = createServer({ root: path.join(project.dir, 'dist') })
|
||||
|
||||
await new Promise((resolve, reject) => {
|
||||
server.listen(port, err => {
|
||||
if (err) return reject(err)
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
|
||||
const launched = await launchPuppeteer(`http://localhost:${port}/demo.html`)
|
||||
browser = launched.browser
|
||||
page = launched.page
|
||||
|
||||
// should expose a module with default and named exports
|
||||
expect(await page.evaluate(() => {
|
||||
return window.testLib.default.foo
|
||||
})).toBe(1)
|
||||
|
||||
expect(await page.evaluate(() => {
|
||||
return window.testLib.bar
|
||||
})).toBe(2)
|
||||
})
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<title><%- htmlWebpackPlugin.options.libName %> demo</title>
|
||||
<script src="./<%- htmlWebpackPlugin.options.libName %>.umd.js"></script>
|
||||
<link rel="stylesheet" href="./<%- htmlWebpackPlugin.options.libName %>.css">
|
||||
|
||||
<script>
|
||||
console.log(<%- htmlWebpackPlugin.options.libName %>)
|
||||
</script>
|
||||
@@ -21,6 +21,7 @@ module.exports = (api, { entry, name }, options) => {
|
||||
)
|
||||
}
|
||||
|
||||
const isVueEntry = /\.vue$/.test(entry)
|
||||
const libName = (
|
||||
name ||
|
||||
api.service.pkg.name ||
|
||||
@@ -57,10 +58,11 @@ module.exports = (api, { entry, name }, options) => {
|
||||
|
||||
// inject demo page for umd
|
||||
if (genHTML) {
|
||||
const template = isVueEntry ? 'demo-lib.html' : 'demo-lib-js.html'
|
||||
config
|
||||
.plugin('demo-html')
|
||||
.use(require('html-webpack-plugin'), [{
|
||||
template: path.resolve(__dirname, './demo-lib.html'),
|
||||
template: path.resolve(__dirname, template),
|
||||
inject: false,
|
||||
filename: 'demo.html',
|
||||
libName
|
||||
@@ -80,21 +82,22 @@ module.exports = (api, { entry, name }, options) => {
|
||||
[entryName]: require.resolve('./entry-lib.js')
|
||||
}
|
||||
|
||||
Object.assign(rawConfig.output, {
|
||||
filename: `${entryName}.js`,
|
||||
chunkFilename: `${entryName}.[name].js`,
|
||||
rawConfig.output = Object.assign({
|
||||
library: libName,
|
||||
libraryExport: 'default',
|
||||
libraryExport: isVueEntry ? 'default' : undefined,
|
||||
libraryTarget: format,
|
||||
// use dynamic publicPath so this can be deployed anywhere
|
||||
// the actual path will be determined at runtime by checking
|
||||
// document.currentScript.src.
|
||||
publicPath: '',
|
||||
// preserve UDM header from webpack 3 until webpack provides either
|
||||
// libraryTarget: 'esm' or target: 'universal'
|
||||
// https://github.com/webpack/webpack/issues/6522
|
||||
// https://github.com/webpack/webpack/issues/6525
|
||||
globalObject: `typeof self !== 'undefined' ? self : this`
|
||||
}, rawConfig.output, {
|
||||
filename: `${entryName}.js`,
|
||||
chunkFilename: `${entryName}.[name].js`,
|
||||
// use dynamic publicPath so this can be deployed anywhere
|
||||
// the actual path will be determined at runtime by checking
|
||||
// document.currentScript.src.
|
||||
publicPath: ''
|
||||
})
|
||||
|
||||
return rawConfig
|
||||
|
||||
Reference in New Issue
Block a user