Skip to content

Commit 3fa0a19

Browse files
authored
Merge pull request #116 from vuejs/technical/fix-esm-biuld
fix: bundle dependencies inline and fix es build
2 parents 418aff7 + 38180a5 commit 3fa0a19

File tree

9 files changed

+199
-60
lines changed

9 files changed

+199
-60
lines changed

package.json

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@
1212
"README.md",
1313
"dist/index.d.ts"
1414
],
15-
"dependencies": {
16-
"dom-event-types": "^1.0.0",
17-
"lodash": "^4.17.15"
18-
},
1915
"devDependencies": {
2016
"@babel/core": "^7.9.0",
2117
"@babel/preset-env": "^7.8.4",
@@ -26,11 +22,12 @@
2622
"@rollup/plugin-replace": "^2.3.2",
2723
"@types/estree": "^0.0.42",
2824
"@types/jest": "^24.9.1",
29-
"@types/lodash": "^4.14.149",
3025
"@types/node": "12.12.35",
26+
"@vue/compiler-dom": "^3.0.0-beta.12",
3127
"@vue/compiler-sfc": "^3.0.0-beta.12",
3228
"babel-jest": "^25.2.3",
3329
"babel-preset-jest": "^25.2.1",
30+
"dom-event-types": "^1.0.0",
3431
"flush-promises": "^1.0.2",
3532
"husky": "^4.2.3",
3633
"jest": "^25.1.0",
@@ -48,6 +45,7 @@
4845
"vuex": "^4.0.0-beta.1"
4946
},
5047
"peerDependencies": {
48+
"@vue/compiler-dom": "^3.0.0-beta.12",
5149
"@vue/compiler-sfc": "^3.0.0-beta.12",
5250
"vue": "^3.0.0-beta.12"
5351
},

rollup.config.js

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ function createEntry(options) {
2626
external: [
2727
'vue',
2828
'@vue/compiler-dom',
29-
'lodash/mergeWith',
30-
'lodash/isString'
3129
],
3230
plugins: [
3331
replace({
@@ -43,30 +41,24 @@ function createEntry(options) {
4341
globals: {
4442
vue: 'Vue',
4543
'@vue/compiler-dom': 'VueCompilerDOM',
46-
'lodash/mergeWith': '_.mergeWith',
47-
'lodash/isString': '_.isString',
4844
}
4945
}
5046
}
5147

52-
if (['es', 'cjs'].includes(format)) {
53-
config.external.push('dom-event-types')
54-
}
55-
5648
if (format === 'es') {
57-
config.output.file = isBrowser ? pkg.browser : pkg.module
49+
config.output.file = pkg.module
5850
}
5951
if (format === 'cjs') {
6052
config.output.file = pkg.main
6153
}
62-
console.log('file is', config.output.file)
54+
console.log(`Building ${format}: ${config.output.file}`)
6355

6456
config.plugins.push(
6557
ts({
6658
check: format === 'es' && isBrowser,
6759
tsconfigOverride: {
6860
compilerOptions: {
69-
declaration: format === 'es' && isBrowser,
61+
declaration: format === 'es',
7062
target: 'es5', // not sure what this should be?
7163
module: format === 'cjs' ? 'es2015' : 'esnext'
7264
},
@@ -80,7 +72,6 @@ function createEntry(options) {
8072

8173
export default [
8274
createEntry({ format: 'es', input: 'src/index.ts', isBrowser: false }),
83-
createEntry({ format: 'es', input: 'src/index.ts', isBrowser: true }),
8475
createEntry({ format: 'iife', input: 'src/index.ts', isBrowser: true }),
8576
createEntry({ format: 'cjs', input: 'src/index.ts', isBrowser: false }),
8677
]

src/create-dom-event.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import * as eventTypes from 'dom-event-types'
1+
import eventTypes from 'dom-event-types'
22

33
interface TriggerOptions {
44
code?: String

src/mount.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,9 @@ export function mount(
142142
ref: MOUNT_COMPONENT_REF
143143
})
144144

145+
const global = mergeGlobalProperties(config.global, options?.global)
146+
component.components = { ...component.components, ...global.components }
147+
145148
// create the wrapper component
146149
const Parent = defineComponent({
147150
name: MOUNT_PARENT_NAME,
@@ -160,7 +163,6 @@ export function mount(
160163

161164
// create the app
162165
const app = createApp(Parent)
163-
const global = mergeGlobalProperties(config.global, options?.global)
164166

165167
// global mocks mixin
166168
if (global?.mocks) {
@@ -176,34 +178,34 @@ export function mount(
176178
}
177179

178180
// AppConfig
179-
if (global?.config) {
181+
if (global.config) {
180182
for (const [k, v] of Object.entries(global.config)) {
181183
app.config[k] = v
182184
}
183185
}
184186

185187
// use and plugins from mounting options
186-
if (global?.plugins) {
188+
if (global.plugins) {
187189
for (const use of global.plugins) app.use(use)
188190
}
189191

190192
// use any mixins from mounting options
191-
if (global?.mixins) {
193+
if (global.mixins) {
192194
for (const mixin of global.mixins) app.mixin(mixin)
193195
}
194196

195-
if (global?.components) {
197+
if (global.components) {
196198
for (const key of Object.keys(global.components))
197199
app.component(key, global.components[key])
198200
}
199201

200-
if (global?.directives) {
202+
if (global.directives) {
201203
for (const key of Object.keys(global.directives))
202204
app.directive(key, global.directives[key])
203205
}
204206

205207
// provide any values passed via provides mounting option
206-
if (global?.provide) {
208+
if (global.provide) {
207209
for (const key of Reflect.ownKeys(global.provide)) {
208210
// @ts-ignore: https://github.com/microsoft/TypeScript/issues/1863
209211
app.provide(key, global.provide[key])
@@ -214,8 +216,8 @@ export function mount(
214216
app.mixin(attachEmitListener())
215217

216218
// stubs
217-
if (options?.global?.stubs || options?.shallow) {
218-
stubComponents(options?.global?.stubs, options?.shallow)
219+
if (global.stubs || options?.shallow) {
220+
stubComponents(global.stubs, options?.shallow)
219221
} else {
220222
transformVNodeArgs()
221223
}

src/utils.ts

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,38 @@
1-
import isString from 'lodash/isString'
2-
import mergeWith from 'lodash/mergeWith'
3-
41
import { GlobalMountOptions } from './types'
52

3+
const isString = (val: unknown): val is string => typeof val === 'string'
4+
5+
function mergeStubs(target, source) {
6+
if (source.stubs) {
7+
if (Array.isArray(source.stubs)) {
8+
source.stubs.forEach((x) => (target[x] = true))
9+
} else {
10+
for (const [k, v] of Object.entries(source.stubs)) {
11+
target[k] = v
12+
}
13+
}
14+
}
15+
}
16+
617
function mergeGlobalProperties(
718
configGlobal: GlobalMountOptions = {},
819
mountGlobal: GlobalMountOptions = {}
920
): GlobalMountOptions {
10-
return mergeWith(
11-
{},
12-
configGlobal,
13-
mountGlobal,
14-
(objValue, srcValue, key: keyof GlobalMountOptions) => {
15-
switch (key) {
16-
case 'mocks':
17-
case 'provide':
18-
case 'components':
19-
case 'directives':
20-
return { ...objValue, ...srcValue }
21-
case 'plugins':
22-
case 'mixins':
23-
return [...(objValue || []), ...(srcValue || [])].filter(Boolean)
24-
}
25-
}
26-
)
21+
const stubs: Record<string, any> = {}
22+
23+
mergeStubs(stubs, configGlobal)
24+
mergeStubs(stubs, mountGlobal)
25+
26+
return {
27+
mixins: [...(configGlobal.mixins || []), ...(mountGlobal.mixins || [])],
28+
plugins: [...(configGlobal.plugins || []), ...(mountGlobal.plugins || [])],
29+
stubs,
30+
components: { ...configGlobal.components, ...mountGlobal.components },
31+
provide: { ...configGlobal.provide, ...mountGlobal.provide },
32+
mocks: { ...configGlobal.mocks, ...mountGlobal.mocks },
33+
config: { ...configGlobal.config, ...mountGlobal.config },
34+
directives: { ...configGlobal.directives, ...mountGlobal.directives }
35+
}
2736
}
2837

2938
export { isString, mergeGlobalProperties }

tests/config.spec.ts

Lines changed: 142 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { h, inject } from 'vue'
12
import { config, mount } from '../src'
23
import Hello from './components/Hello.vue'
34

@@ -11,20 +12,33 @@ describe('config', () => {
1112
mocks: undefined,
1213
provide: undefined
1314
}
15+
16+
jest.clearAllMocks()
1417
})
1518

1619
describe('components', () => {
1720
const Component = {
18-
template: '<div>{{ msg }} <hello/></div>',
21+
components: { Hello },
22+
template: '<div>{{ msg }} <Hello /></div>',
1923
props: ['msg']
2024
}
2125

2226
it('allows setting components globally', () => {
23-
config.global.components = { Hello }
24-
const wrapper1 = mount(Component, { props: { msg: 'Wrapper1' } })
25-
const wrapper2 = mount(Component, { props: { msg: 'Wrapper2' } })
26-
expect(wrapper1.text()).toEqual('Wrapper1 Hello world')
27-
expect(wrapper2.text()).toEqual('Wrapper2 Hello world')
27+
const HelloLocal = {
28+
name: 'Hello',
29+
render() {
30+
return h('div', 'Hello Local')
31+
}
32+
}
33+
config.global.components = { Hello: HelloLocal }
34+
const wrapper1 = mount(Component, {
35+
props: { msg: 'Wrapper1' }
36+
})
37+
const wrapper2 = mount(Component, {
38+
props: { msg: 'Wrapper2' }
39+
})
40+
expect(wrapper1.text()).toEqual('Wrapper1 Hello Local')
41+
expect(wrapper2.text()).toEqual('Wrapper2 Hello Local')
2842
})
2943

3044
it('allows overwriting globally set component config on a per mount instance', () => {
@@ -93,4 +107,126 @@ describe('config', () => {
93107
).toEqual('baz')
94108
})
95109
})
110+
111+
describe('provide', () => {
112+
const Comp = {
113+
setup() {
114+
const theme = inject('theme')
115+
return () => h('div', theme)
116+
}
117+
}
118+
119+
it('sets a provide everywhere', () => {
120+
config.global.provide = {
121+
theme: 'dark'
122+
}
123+
const wrapper = mount(Comp)
124+
expect(wrapper.html()).toContain('dark')
125+
})
126+
127+
it('overrides with a local provide', () => {
128+
config.global.provide = {
129+
theme: 'dark'
130+
}
131+
const wrapper = mount(Comp, {
132+
global: {
133+
provide: {
134+
theme: 'light'
135+
}
136+
}
137+
})
138+
expect(wrapper.html()).toContain('light')
139+
})
140+
})
141+
142+
describe('mixins', () => {
143+
const createdHook = jest.fn()
144+
const mixin = {
145+
created() {
146+
createdHook()
147+
}
148+
}
149+
const Component = {
150+
render() {
151+
return h('div')
152+
}
153+
}
154+
155+
it('sets a mixin everywhere', () => {
156+
config.global.mixins = [mixin]
157+
mount(Component)
158+
159+
// once on root, once in the mounted component
160+
expect(createdHook).toHaveBeenCalledTimes(2)
161+
})
162+
163+
it('concats with locally defined mixins', () => {
164+
config.global.mixins = [mixin]
165+
const localHook = jest.fn()
166+
const localMixin = {
167+
created() {
168+
localHook(this.$options.name)
169+
}
170+
}
171+
172+
mount(Component, {
173+
global: {
174+
mixins: [localMixin]
175+
}
176+
})
177+
178+
// once on root, once in the mounted component
179+
expect(localHook).toHaveBeenCalledTimes(2)
180+
expect(createdHook).toHaveBeenCalledTimes(2)
181+
})
182+
})
183+
184+
describe('stubs', () => {
185+
const Foo = {
186+
name: 'Foo',
187+
render() {
188+
return h('div', 'real foo')
189+
}
190+
}
191+
192+
const Component = {
193+
render() {
194+
return h('div', h(Foo))
195+
}
196+
}
197+
198+
beforeEach(() => {
199+
config.global.stubs = {
200+
Foo: {
201+
name: 'Foo',
202+
render() {
203+
return h('div', 'config foo stub')
204+
}
205+
}
206+
}
207+
})
208+
209+
it('sets a stub globally', () => {
210+
const wrapper = mount(Component)
211+
212+
// once on root, once in the mounted component
213+
expect(wrapper.html()).toContain('config foo stub')
214+
})
215+
216+
it('overrides config stub with locally defined stub', () => {
217+
const wrapper = mount(Component, {
218+
global: {
219+
stubs: {
220+
Foo: {
221+
render() {
222+
return h('div', 'local foo stub')
223+
}
224+
}
225+
}
226+
}
227+
})
228+
229+
expect(wrapper.html()).toContain('local foo stub')
230+
})
231+
})
96232
})

0 commit comments

Comments
 (0)