Skip to content

Commit

Permalink
Merge pull request #116 from vuejs/technical/fix-esm-biuld
Browse files Browse the repository at this point in the history
fix: bundle dependencies inline and fix es build
  • Loading branch information
lmiller1990 committed May 13, 2020
2 parents 418aff7 + 38180a5 commit 3fa0a19
Show file tree
Hide file tree
Showing 9 changed files with 199 additions and 60 deletions.
8 changes: 3 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@
"README.md",
"dist/index.d.ts"
],
"dependencies": {
"dom-event-types": "^1.0.0",
"lodash": "^4.17.15"
},
"devDependencies": {
"@babel/core": "^7.9.0",
"@babel/preset-env": "^7.8.4",
Expand All @@ -26,11 +22,12 @@
"@rollup/plugin-replace": "^2.3.2",
"@types/estree": "^0.0.42",
"@types/jest": "^24.9.1",
"@types/lodash": "^4.14.149",
"@types/node": "12.12.35",
"@vue/compiler-dom": "^3.0.0-beta.12",
"@vue/compiler-sfc": "^3.0.0-beta.12",
"babel-jest": "^25.2.3",
"babel-preset-jest": "^25.2.1",
"dom-event-types": "^1.0.0",
"flush-promises": "^1.0.2",
"husky": "^4.2.3",
"jest": "^25.1.0",
Expand All @@ -48,6 +45,7 @@
"vuex": "^4.0.0-beta.1"
},
"peerDependencies": {
"@vue/compiler-dom": "^3.0.0-beta.12",
"@vue/compiler-sfc": "^3.0.0-beta.12",
"vue": "^3.0.0-beta.12"
},
Expand Down
15 changes: 3 additions & 12 deletions rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ function createEntry(options) {
external: [
'vue',
'@vue/compiler-dom',
'lodash/mergeWith',
'lodash/isString'
],
plugins: [
replace({
Expand All @@ -43,30 +41,24 @@ function createEntry(options) {
globals: {
vue: 'Vue',
'@vue/compiler-dom': 'VueCompilerDOM',
'lodash/mergeWith': '_.mergeWith',
'lodash/isString': '_.isString',
}
}
}

if (['es', 'cjs'].includes(format)) {
config.external.push('dom-event-types')
}

if (format === 'es') {
config.output.file = isBrowser ? pkg.browser : pkg.module
config.output.file = pkg.module
}
if (format === 'cjs') {
config.output.file = pkg.main
}
console.log('file is', config.output.file)
console.log(`Building ${format}: ${config.output.file}`)

config.plugins.push(
ts({
check: format === 'es' && isBrowser,
tsconfigOverride: {
compilerOptions: {
declaration: format === 'es' && isBrowser,
declaration: format === 'es',
target: 'es5', // not sure what this should be?
module: format === 'cjs' ? 'es2015' : 'esnext'
},
Expand All @@ -80,7 +72,6 @@ function createEntry(options) {

export default [
createEntry({ format: 'es', input: 'src/index.ts', isBrowser: false }),
createEntry({ format: 'es', input: 'src/index.ts', isBrowser: true }),
createEntry({ format: 'iife', input: 'src/index.ts', isBrowser: true }),
createEntry({ format: 'cjs', input: 'src/index.ts', isBrowser: false }),
]
2 changes: 1 addition & 1 deletion src/create-dom-event.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as eventTypes from 'dom-event-types'
import eventTypes from 'dom-event-types'

interface TriggerOptions {
code?: String
Expand Down
20 changes: 11 additions & 9 deletions src/mount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ export function mount(
ref: MOUNT_COMPONENT_REF
})

const global = mergeGlobalProperties(config.global, options?.global)
component.components = { ...component.components, ...global.components }

// create the wrapper component
const Parent = defineComponent({
name: MOUNT_PARENT_NAME,
Expand All @@ -160,7 +163,6 @@ export function mount(

// create the app
const app = createApp(Parent)
const global = mergeGlobalProperties(config.global, options?.global)

// global mocks mixin
if (global?.mocks) {
Expand All @@ -176,34 +178,34 @@ export function mount(
}

// AppConfig
if (global?.config) {
if (global.config) {
for (const [k, v] of Object.entries(global.config)) {
app.config[k] = v
}
}

// use and plugins from mounting options
if (global?.plugins) {
if (global.plugins) {
for (const use of global.plugins) app.use(use)
}

// use any mixins from mounting options
if (global?.mixins) {
if (global.mixins) {
for (const mixin of global.mixins) app.mixin(mixin)
}

if (global?.components) {
if (global.components) {
for (const key of Object.keys(global.components))
app.component(key, global.components[key])
}

if (global?.directives) {
if (global.directives) {
for (const key of Object.keys(global.directives))
app.directive(key, global.directives[key])
}

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

// stubs
if (options?.global?.stubs || options?.shallow) {
stubComponents(options?.global?.stubs, options?.shallow)
if (global.stubs || options?.shallow) {
stubComponents(global.stubs, options?.shallow)
} else {
transformVNodeArgs()
}
Expand Down
49 changes: 29 additions & 20 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,38 @@
import isString from 'lodash/isString'
import mergeWith from 'lodash/mergeWith'

import { GlobalMountOptions } from './types'

const isString = (val: unknown): val is string => typeof val === 'string'

function mergeStubs(target, source) {
if (source.stubs) {
if (Array.isArray(source.stubs)) {
source.stubs.forEach((x) => (target[x] = true))
} else {
for (const [k, v] of Object.entries(source.stubs)) {
target[k] = v
}
}
}
}

function mergeGlobalProperties(
configGlobal: GlobalMountOptions = {},
mountGlobal: GlobalMountOptions = {}
): GlobalMountOptions {
return mergeWith(
{},
configGlobal,
mountGlobal,
(objValue, srcValue, key: keyof GlobalMountOptions) => {
switch (key) {
case 'mocks':
case 'provide':
case 'components':
case 'directives':
return { ...objValue, ...srcValue }
case 'plugins':
case 'mixins':
return [...(objValue || []), ...(srcValue || [])].filter(Boolean)
}
}
)
const stubs: Record<string, any> = {}

mergeStubs(stubs, configGlobal)
mergeStubs(stubs, mountGlobal)

return {
mixins: [...(configGlobal.mixins || []), ...(mountGlobal.mixins || [])],
plugins: [...(configGlobal.plugins || []), ...(mountGlobal.plugins || [])],
stubs,
components: { ...configGlobal.components, ...mountGlobal.components },
provide: { ...configGlobal.provide, ...mountGlobal.provide },
mocks: { ...configGlobal.mocks, ...mountGlobal.mocks },
config: { ...configGlobal.config, ...mountGlobal.config },
directives: { ...configGlobal.directives, ...mountGlobal.directives }
}
}

export { isString, mergeGlobalProperties }
148 changes: 142 additions & 6 deletions tests/config.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { h, inject } from 'vue'
import { config, mount } from '../src'
import Hello from './components/Hello.vue'

Expand All @@ -11,20 +12,33 @@ describe('config', () => {
mocks: undefined,
provide: undefined
}

jest.clearAllMocks()
})

describe('components', () => {
const Component = {
template: '<div>{{ msg }} <hello/></div>',
components: { Hello },
template: '<div>{{ msg }} <Hello /></div>',
props: ['msg']
}

it('allows setting components globally', () => {
config.global.components = { Hello }
const wrapper1 = mount(Component, { props: { msg: 'Wrapper1' } })
const wrapper2 = mount(Component, { props: { msg: 'Wrapper2' } })
expect(wrapper1.text()).toEqual('Wrapper1 Hello world')
expect(wrapper2.text()).toEqual('Wrapper2 Hello world')
const HelloLocal = {
name: 'Hello',
render() {
return h('div', 'Hello Local')
}
}
config.global.components = { Hello: HelloLocal }
const wrapper1 = mount(Component, {
props: { msg: 'Wrapper1' }
})
const wrapper2 = mount(Component, {
props: { msg: 'Wrapper2' }
})
expect(wrapper1.text()).toEqual('Wrapper1 Hello Local')
expect(wrapper2.text()).toEqual('Wrapper2 Hello Local')
})

it('allows overwriting globally set component config on a per mount instance', () => {
Expand Down Expand Up @@ -93,4 +107,126 @@ describe('config', () => {
).toEqual('baz')
})
})

describe('provide', () => {
const Comp = {
setup() {
const theme = inject('theme')
return () => h('div', theme)
}
}

it('sets a provide everywhere', () => {
config.global.provide = {
theme: 'dark'
}
const wrapper = mount(Comp)
expect(wrapper.html()).toContain('dark')
})

it('overrides with a local provide', () => {
config.global.provide = {
theme: 'dark'
}
const wrapper = mount(Comp, {
global: {
provide: {
theme: 'light'
}
}
})
expect(wrapper.html()).toContain('light')
})
})

describe('mixins', () => {
const createdHook = jest.fn()
const mixin = {
created() {
createdHook()
}
}
const Component = {
render() {
return h('div')
}
}

it('sets a mixin everywhere', () => {
config.global.mixins = [mixin]
mount(Component)

// once on root, once in the mounted component
expect(createdHook).toHaveBeenCalledTimes(2)
})

it('concats with locally defined mixins', () => {
config.global.mixins = [mixin]
const localHook = jest.fn()
const localMixin = {
created() {
localHook(this.$options.name)
}
}

mount(Component, {
global: {
mixins: [localMixin]
}
})

// once on root, once in the mounted component
expect(localHook).toHaveBeenCalledTimes(2)
expect(createdHook).toHaveBeenCalledTimes(2)
})
})

describe('stubs', () => {
const Foo = {
name: 'Foo',
render() {
return h('div', 'real foo')
}
}

const Component = {
render() {
return h('div', h(Foo))
}
}

beforeEach(() => {
config.global.stubs = {
Foo: {
name: 'Foo',
render() {
return h('div', 'config foo stub')
}
}
}
})

it('sets a stub globally', () => {
const wrapper = mount(Component)

// once on root, once in the mounted component
expect(wrapper.html()).toContain('config foo stub')
})

it('overrides config stub with locally defined stub', () => {
const wrapper = mount(Component, {
global: {
stubs: {
Foo: {
render() {
return h('div', 'local foo stub')
}
}
}
}
})

expect(wrapper.html()).toContain('local foo stub')
})
})
})

0 comments on commit 3fa0a19

Please sign in to comment.