Skip to content

Commit 6e29d3e

Browse files
committed
feat(build): Add keepVueInstance config option to avoid externalization of Vue when build target is Lib.
Resolves #4055.
1 parent 3289e10 commit 6e29d3e

File tree

3 files changed

+69
-4
lines changed

3 files changed

+69
-4
lines changed

packages/@vue/cli-service/__tests__/buildLib.spec.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,3 +174,65 @@ test('build as lib with --filename option', async () => {
174174
return window.testLib.bar
175175
})).toBe(2)
176176
})
177+
178+
test('build as lib with keepVueInstance true', async () => {
179+
const project = await create('build-lib-keep-vue-instance', defaultPreset)
180+
181+
await project.write('src/main-lib.js', `
182+
import Vue from 'vue'
183+
import App from "./components/App.vue"
184+
185+
document.addEventListener("DOMContentLoaded", function() {
186+
new Vue({
187+
render: h => h(App),
188+
}).$mount('body');
189+
});
190+
`)
191+
192+
await project.write('src/components/App.vue', `
193+
<template>
194+
<div>{{ message }}<div>
195+
</template>
196+
<script>
197+
export default {
198+
data() {
199+
return {
200+
message: 'Hello from Lib'
201+
}
202+
},
203+
}
204+
</script>
205+
`)
206+
207+
await project.write('vue.config.js', `
208+
module.exports = {
209+
keepVueInstance: true
210+
}
211+
`)
212+
213+
const { stdout } = await project.run('vue-cli-service build --target lib --name testLib src/main-lib.js')
214+
expect(stdout).toMatch('Build complete.')
215+
216+
expect(project.has('dist/demo.html')).toBe(true)
217+
expect(project.has('dist/testLib.common.js')).toBe(true)
218+
expect(project.has('dist/testLib.umd.js')).toBe(true)
219+
expect(project.has('dist/testLib.umd.min.js')).toBe(true)
220+
221+
const port = await portfinder.getPortPromise()
222+
server = createServer({ root: path.join(project.dir, 'dist') })
223+
224+
await new Promise((resolve, reject) => {
225+
server.listen(port, err => {
226+
if (err) return reject(err)
227+
resolve()
228+
})
229+
})
230+
231+
const launched = await launchPuppeteer(`http://localhost:${port}/demo.html`)
232+
browser = launched.browser
233+
page = launched.page
234+
const divText = await page.evaluate(() => {
235+
return document.querySelector('div').textContent
236+
})
237+
expect(divText).toMatch('Hello from Lib')
238+
})

packages/@vue/cli-service/lib/commands/build/resolveLibConfig.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,17 @@ module.exports = (api, { entry, name, formats, filename }, options) => {
5454
}
5555

5656
// externalize Vue in case user imports it
57-
config
58-
.externals({
59-
...config.get('externals'),
57+
// but avoid it, if config explicitly specify to keep it
58+
config.externals({
59+
...config.get('externals'),
60+
...(!api.service.projectOptions.keepVueInstance ? {
6061
vue: {
6162
commonjs: 'vue',
6263
commonjs2: 'vue',
6364
root: 'Vue'
6465
}
65-
})
66+
} : {})
67+
})
6668

6769
// inject demo page for umd
6870
if (genHTML) {

packages/@vue/cli-service/lib/options.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ const schema = createSchema(joi => joi.object({
3131
),
3232
crossorigin: joi.string().valid(['', 'anonymous', 'use-credentials']),
3333
integrity: joi.boolean(),
34+
keepVueInstance: joi.boolean(),
3435

3536
// css
3637
css: joi.object({

0 commit comments

Comments
 (0)