diff --git a/create-snowpack-app/app-template-11ty/_output/static/logo.svg b/create-snowpack-app/app-template-11ty/_output/static/logo.svg index 493a6d28e7..fb5518f5f9 100644 --- a/create-snowpack-app/app-template-11ty/_output/static/logo.svg +++ b/create-snowpack-app/app-template-11ty/_output/static/logo.svg @@ -1 +1 @@ - + \ No newline at end of file diff --git a/plugins/plugin-vue/README.md b/plugins/plugin-vue/README.md index d5de9c4325..694530fe6d 100644 --- a/plugins/plugin-vue/README.md +++ b/plugins/plugin-vue/README.md @@ -9,10 +9,20 @@ npm install --save-dev @snowpack/plugin-vue ```js // snowpack.config.mjs export default { - plugins: ['@snowpack/plugin-vue'], + plugins: [ + '@snowpack/plugin-vue', + { + /* see optional “Plugin Options” below */ + }, + ], }; ``` -#### Plugin Options +## Plugin Options -(none) +You may customize Vue's bundler behavior using the following plugin options. + +| Name | Type | Description | +| :------------- | :-------: | :--------------------------------------------------------------------------------------------------- | +| `optionsApi` | `boolean` | Enable/disable [Options API](https://v3.vuejs.org/api/options-api.html) support. Defaults to `true`. | +| `prodDevtools` | `boolean` | Enable/disable devtools support in production. Defaults to `false`. | diff --git a/plugins/plugin-vue/package.json b/plugins/plugin-vue/package.json index 691fc72176..4c09fbbee2 100644 --- a/plugins/plugin-vue/package.json +++ b/plugins/plugin-vue/package.json @@ -13,6 +13,7 @@ "access": "public" }, "dependencies": { + "@rollup/plugin-replace": "^2.4.2", "@vue/compiler-sfc": "^3.0.10", "hash-sum": "^2.0.0" }, diff --git a/plugins/plugin-vue/plugin.js b/plugins/plugin-vue/plugin.js index 2e3cc36ee7..c1899ce6bf 100644 --- a/plugins/plugin-vue/plugin.js +++ b/plugins/plugin-vue/plugin.js @@ -3,6 +3,7 @@ const path = require('path'); const hashsum = require('hash-sum'); const compiler = require('@vue/compiler-sfc'); const scriptCompilers = require('./src/script-compilers'); +const replace = require('@rollup/plugin-replace'); const inlineSourcemap = (code, map) => code + @@ -37,7 +38,23 @@ function displayError({contents, filePath, error}) { return output.join('\n'); } -module.exports = function plugin(snowpackConfig) { +module.exports = function plugin(snowpackConfig, pluginOptions = {}) { + // Enable proper tree-shaking for Vue's ESM bundler + // See http://link.vuejs.org/feature-flags + const packageOptions = snowpackConfig.packageOptions || snowpackConfig.installOptions; + if (packageOptions && packageOptions.source === 'local') { + packageOptions.rollup = packageOptions.rollup || {}; + packageOptions.rollup.plugins = packageOptions.rollup.plugins || []; + const {optionsApi = true, prodDevtools = false} = pluginOptions; + packageOptions.rollup.plugins.push( + replace({ + values: { + __VUE_OPTIONS_API__: JSON.stringify(optionsApi), + __VUE_PROD_DEVTOOLS__: JSON.stringify(prodDevtools), + }, + }), + ); + } return { name: '@snowpack/plugin-vue', resolve: { diff --git a/test/create-snowpack-app/__snapshots__/create-snowpack-app.test.js.snap b/test/create-snowpack-app/__snapshots__/create-snowpack-app.test.js.snap index 65af16ffd1..0759f4f964 100644 --- a/test/create-snowpack-app/__snapshots__/create-snowpack-app.test.js.snap +++ b/test/create-snowpack-app/__snapshots__/create-snowpack-app.test.js.snap @@ -7031,7 +7031,7 @@ exports[`create-snowpack-app app-template-minimal > build: package.json 1`] = ` "{ \\"name\\": \\"@snowpack/app-template-minimal\\", \\"description\\": \\"A preconfigured minimal template for Snowpack\\", - \\"version\\": \\"2.1.0\\", + \\"version\\": \\"2.1.1\\", \\"license\\": \\"MIT\\", \\"homepage\\": \\"https://github.com/snowpackjs/snowpack/tree/main/create-snowpack-app/app-template-preact#readme\\", \\"repository\\": { @@ -9141,20 +9141,6 @@ const toNumber = (val) => { const n = parseFloat(val); return isNaN(n) ? val : n; }; -let _globalThis; -const getGlobalThis = () => { - return (_globalThis || - (_globalThis = - typeof globalThis !== 'undefined' - ? globalThis - : typeof self !== 'undefined' - ? self - : typeof window !== 'undefined' - ? window - : typeof global !== 'undefined' - ? global - : {})); -}; const targetMap = new WeakMap(); const effectStack = []; let activeEffect; @@ -10235,41 +10221,6 @@ function checkRecursiveUpdates(seen, fn) { } } } -let devtools; -function setDevtoolsHook(hook) { - devtools = hook; -} -function devtoolsInitApp(app, version) { - // TODO queue if devtools is undefined - if (!devtools) - return; - devtools.emit(\\"app:init\\" /* APP_INIT */, app, version, { - Fragment, - Text, - Comment, - Static - }); -} -function devtoolsUnmountApp(app) { - if (!devtools) - return; - devtools.emit(\\"app:unmount\\" /* APP_UNMOUNT */, app); -} -const devtoolsComponentAdded = /*#__PURE__*/ createDevtoolsComponentHook(\\"component:added\\" /* COMPONENT_ADDED */); -const devtoolsComponentUpdated = /*#__PURE__*/ createDevtoolsComponentHook(\\"component:updated\\" /* COMPONENT_UPDATED */); -const devtoolsComponentRemoved = /*#__PURE__*/ createDevtoolsComponentHook(\\"component:removed\\" /* COMPONENT_REMOVED */); -function createDevtoolsComponentHook(hook) { - return (component) => { - if (!devtools) - return; - devtools.emit(hook, component.appContext.app, component.uid, component.parent ? component.parent.uid : undefined, component); - }; -} -function devtoolsComponentEmit(component, event, params) { - if (!devtools) - return; - devtools.emit(\\"component:emit\\" /* COMPONENT_EMIT */, component.appContext.app, component, event, params); -} function emit(instance, event, ...rawArgs) { const props = instance.vnode.props || EMPTY_OBJ; let args = rawArgs; @@ -10286,9 +10237,6 @@ function emit(instance, event, ...rawArgs) { args = rawArgs.map(toNumber); } } - if ( __VUE_PROD_DEVTOOLS__) { - devtoolsComponentEmit(instance, event, args); - } let handlerName; let handler = props[(handlerName = toHandlerKey(event))] || // also try camelCase event handler (#2249) @@ -10320,7 +10268,7 @@ function normalizeEmitsOptions(comp, appContext, asMixin = false) { let normalized = {}; // apply mixin/extends props let hasExtends = false; - if (__VUE_OPTIONS_API__ && !isFunction(comp)) { + if ( !isFunction(comp)) { const extendEmits = (raw) => { const normalizedFromExtend = normalizeEmitsOptions(raw, appContext, true); if (normalizedFromExtend) { @@ -10867,7 +10815,7 @@ function normalizePropsOptions(comp, appContext, asMixin = false) { const needCastKeys = []; // apply mixin/extends props let hasExtends = false; - if (__VUE_OPTIONS_API__ && !isFunction(comp)) { + if ( !isFunction(comp)) { const extendProps = (raw) => { hasExtends = true; const [props, keys] = normalizePropsOptions(raw, appContext, true); @@ -11378,7 +11326,7 @@ function createAppAPI(render, hydrate) { return app; }, mixin(mixin) { - if (__VUE_OPTIONS_API__) { + { if (!context.mixins.includes(mixin)) { context.mixins.push(mixin); // global mixin with props/emits de-optimizes props/emits @@ -11419,18 +11367,12 @@ function createAppAPI(render, hydrate) { isMounted = true; app._container = rootContainer; rootContainer.__vue_app__ = app; - if ( __VUE_PROD_DEVTOOLS__) { - devtoolsInitApp(app, version); - } return vnode.component.proxy; } }, unmount() { if (isMounted) { render(null, app._container); - if ( __VUE_PROD_DEVTOOLS__) { - devtoolsUnmountApp(app); - } delete app._container.__vue_app__; } }, @@ -11444,21 +11386,6 @@ function createAppAPI(render, hydrate) { return app; }; } -/** - * This is only called in esm-bundler builds. - * It is called when a renderer is created, in \`baseCreateRenderer\` so that - * importing runtime-core is side-effects free. - * - * istanbul-ignore-next - */ -function initFeatureFlags() { - if (typeof __VUE_OPTIONS_API__ !== 'boolean') { - getGlobalThis().__VUE_OPTIONS_API__ = true; - } - if (typeof __VUE_PROD_DEVTOOLS__ !== 'boolean') { - getGlobalThis().__VUE_PROD_DEVTOOLS__ = false; - } -} const isAsyncWrapper = (i) => !!i.type.__asyncLoader; const prodEffectOptions = { scheduler: queueJob, @@ -11559,15 +11486,6 @@ function createRenderer(options) { } // implementation function baseCreateRenderer(options, createHydrationFns) { - // compile-time feature flags check - { - initFeatureFlags(); - } - if ( __VUE_PROD_DEVTOOLS__) { - const target = getGlobalThis(); - target.__VUE__ = true; - setDevtoolsHook(target.__VUE_DEVTOOLS_GLOBAL_HOOK__); - } const { insert: hostInsert, remove: hostRemove, patchProp: hostPatchProp, forcePatchProp: hostForcePatchProp, createElement: hostCreateElement, createText: hostCreateText, createComment: hostCreateComment, setText: hostSetText, setElementText: hostSetElementText, parentNode: hostParentNode, nextSibling: hostNextSibling, setScopeId: hostSetScopeId = NOOP, cloneNode: hostCloneNode, insertStaticContent: hostInsertStaticContent } = options; // Note: functions inside this closure should use \`const xxx = () => {}\` // style in order to prevent being inlined by minifiers. @@ -11709,16 +11627,6 @@ function baseCreateRenderer(options, createHydrationFns) { // scopeId setScopeId(el, vnode, vnode.scopeId, slotScopeIds, parentComponent); } - if ( __VUE_PROD_DEVTOOLS__) { - Object.defineProperty(el, '__vnode', { - value: vnode, - enumerable: false - }); - Object.defineProperty(el, '__vueParentComponent', { - value: parentComponent, - enumerable: false - }); - } if (dirs) { invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount'); } @@ -12049,9 +11957,6 @@ function baseCreateRenderer(options, createHydrationFns) { queuePostRenderEffect(a, parentSuspense); } instance.isMounted = true; - if ( __VUE_PROD_DEVTOOLS__) { - devtoolsComponentAdded(instance); - } // #2458: deference mount-only object parameters to prevent memleaks initialVNode = container = anchor = null; } @@ -12102,9 +12007,6 @@ function baseCreateRenderer(options, createHydrationFns) { invokeVNodeHook(vnodeHook, parent, next, vnode); }, parentSuspense); } - if ( __VUE_PROD_DEVTOOLS__) { - devtoolsComponentUpdated(instance); - } } }, prodEffectOptions); }; @@ -12558,9 +12460,6 @@ function baseCreateRenderer(options, createHydrationFns) { parentSuspense.resolve(); } } - if ( __VUE_PROD_DEVTOOLS__) { - devtoolsComponentRemoved(instance); - } }; const unmountChildren = (children, parentComponent, parentSuspense, doRemove = false, optimized = false, start = 0) => { for (let i = start; i < children.length; i++) { @@ -13395,10 +13294,10 @@ const publicPropertiesMap = extend(Object.create(null), { $parent: i => getPublicInstance(i.parent), $root: i => getPublicInstance(i.root), $emit: i => i.emit, - $options: i => (__VUE_OPTIONS_API__ ? resolveMergedOptions(i) : i.type), + $options: i => ( resolveMergedOptions(i) ), $forceUpdate: i => () => queueJob(i.update), $nextTick: i => nextTick.bind(i.proxy), - $watch: i => (__VUE_OPTIONS_API__ ? instanceWatch.bind(i) : NOOP) + $watch: i => ( instanceWatch.bind(i) ) }); const PublicInstanceProxyHandlers = { get({ _: instance }, key) { @@ -13449,7 +13348,7 @@ const PublicInstanceProxyHandlers = { accessCache[key] = 3 /* CONTEXT */; return ctx[key]; } - else if (!__VUE_OPTIONS_API__ || shouldCacheAccess) { + else if ( shouldCacheAccess) { accessCache[key] = 4 /* OTHER */; } } @@ -13671,11 +13570,6 @@ function handleSetupResult(instance, setupResult, isSSR) { } } else if (isObject(setupResult)) { - // setup returned bindings. - // assuming a render function compiled from template is present. - if ( __VUE_PROD_DEVTOOLS__) { - instance.devtoolsRawSetupState = setupResult; - } instance.setupState = proxyRefs(setupResult); } else ; @@ -13694,7 +13588,7 @@ function finishComponentSetup(instance, isSSR) { } } // support for 2.x options - if (__VUE_OPTIONS_API__) { + { currentInstance = instance; pauseTracking(); applyOptions(instance, Component); @@ -14585,20 +14479,6 @@ const toNumber = (val) => { const n = parseFloat(val); return isNaN(n) ? val : n; }; -let _globalThis; -const getGlobalThis = () => { - return (_globalThis || - (_globalThis = - typeof globalThis !== 'undefined' - ? globalThis - : typeof self !== 'undefined' - ? self - : typeof window !== 'undefined' - ? window - : typeof global !== 'undefined' - ? global - : {})); -}; const targetMap = new WeakMap(); const effectStack = []; let activeEffect; @@ -15679,41 +15559,6 @@ function checkRecursiveUpdates(seen, fn) { } } } -let devtools; -function setDevtoolsHook(hook) { - devtools = hook; -} -function devtoolsInitApp(app, version) { - // TODO queue if devtools is undefined - if (!devtools) - return; - devtools.emit(\\"app:init\\" /* APP_INIT */, app, version, { - Fragment, - Text, - Comment, - Static - }); -} -function devtoolsUnmountApp(app) { - if (!devtools) - return; - devtools.emit(\\"app:unmount\\" /* APP_UNMOUNT */, app); -} -const devtoolsComponentAdded = /*#__PURE__*/ createDevtoolsComponentHook(\\"component:added\\" /* COMPONENT_ADDED */); -const devtoolsComponentUpdated = /*#__PURE__*/ createDevtoolsComponentHook(\\"component:updated\\" /* COMPONENT_UPDATED */); -const devtoolsComponentRemoved = /*#__PURE__*/ createDevtoolsComponentHook(\\"component:removed\\" /* COMPONENT_REMOVED */); -function createDevtoolsComponentHook(hook) { - return (component) => { - if (!devtools) - return; - devtools.emit(hook, component.appContext.app, component.uid, component.parent ? component.parent.uid : undefined, component); - }; -} -function devtoolsComponentEmit(component, event, params) { - if (!devtools) - return; - devtools.emit(\\"component:emit\\" /* COMPONENT_EMIT */, component.appContext.app, component, event, params); -} function emit(instance, event, ...rawArgs) { const props = instance.vnode.props || EMPTY_OBJ; let args = rawArgs; @@ -15730,9 +15575,6 @@ function emit(instance, event, ...rawArgs) { args = rawArgs.map(toNumber); } } - if ( __VUE_PROD_DEVTOOLS__) { - devtoolsComponentEmit(instance, event, args); - } let handlerName; let handler = props[(handlerName = toHandlerKey(event))] || // also try camelCase event handler (#2249) @@ -15764,7 +15606,7 @@ function normalizeEmitsOptions(comp, appContext, asMixin = false) { let normalized = {}; // apply mixin/extends props let hasExtends = false; - if (__VUE_OPTIONS_API__ && !isFunction(comp)) { + if ( !isFunction(comp)) { const extendEmits = (raw) => { const normalizedFromExtend = normalizeEmitsOptions(raw, appContext, true); if (normalizedFromExtend) { @@ -16311,7 +16153,7 @@ function normalizePropsOptions(comp, appContext, asMixin = false) { const needCastKeys = []; // apply mixin/extends props let hasExtends = false; - if (__VUE_OPTIONS_API__ && !isFunction(comp)) { + if ( !isFunction(comp)) { const extendProps = (raw) => { hasExtends = true; const [props, keys] = normalizePropsOptions(raw, appContext, true); @@ -16822,7 +16664,7 @@ function createAppAPI(render, hydrate) { return app; }, mixin(mixin) { - if (__VUE_OPTIONS_API__) { + { if (!context.mixins.includes(mixin)) { context.mixins.push(mixin); // global mixin with props/emits de-optimizes props/emits @@ -16863,18 +16705,12 @@ function createAppAPI(render, hydrate) { isMounted = true; app._container = rootContainer; rootContainer.__vue_app__ = app; - if ( __VUE_PROD_DEVTOOLS__) { - devtoolsInitApp(app, version); - } return vnode.component.proxy; } }, unmount() { if (isMounted) { render(null, app._container); - if ( __VUE_PROD_DEVTOOLS__) { - devtoolsUnmountApp(app); - } delete app._container.__vue_app__; } }, @@ -16888,21 +16724,6 @@ function createAppAPI(render, hydrate) { return app; }; } -/** - * This is only called in esm-bundler builds. - * It is called when a renderer is created, in \`baseCreateRenderer\` so that - * importing runtime-core is side-effects free. - * - * istanbul-ignore-next - */ -function initFeatureFlags() { - if (typeof __VUE_OPTIONS_API__ !== 'boolean') { - getGlobalThis().__VUE_OPTIONS_API__ = true; - } - if (typeof __VUE_PROD_DEVTOOLS__ !== 'boolean') { - getGlobalThis().__VUE_PROD_DEVTOOLS__ = false; - } -} // implementation, close to no-op function defineComponent(options) { return isFunction(options) ? { setup: options, name: options.name } : options; @@ -17007,15 +16828,6 @@ function createRenderer(options) { } // implementation function baseCreateRenderer(options, createHydrationFns) { - // compile-time feature flags check - { - initFeatureFlags(); - } - if ( __VUE_PROD_DEVTOOLS__) { - const target = getGlobalThis(); - target.__VUE__ = true; - setDevtoolsHook(target.__VUE_DEVTOOLS_GLOBAL_HOOK__); - } const { insert: hostInsert, remove: hostRemove, patchProp: hostPatchProp, forcePatchProp: hostForcePatchProp, createElement: hostCreateElement, createText: hostCreateText, createComment: hostCreateComment, setText: hostSetText, setElementText: hostSetElementText, parentNode: hostParentNode, nextSibling: hostNextSibling, setScopeId: hostSetScopeId = NOOP, cloneNode: hostCloneNode, insertStaticContent: hostInsertStaticContent } = options; // Note: functions inside this closure should use \`const xxx = () => {}\` // style in order to prevent being inlined by minifiers. @@ -17157,16 +16969,6 @@ function baseCreateRenderer(options, createHydrationFns) { // scopeId setScopeId(el, vnode, vnode.scopeId, slotScopeIds, parentComponent); } - if ( __VUE_PROD_DEVTOOLS__) { - Object.defineProperty(el, '__vnode', { - value: vnode, - enumerable: false - }); - Object.defineProperty(el, '__vueParentComponent', { - value: parentComponent, - enumerable: false - }); - } if (dirs) { invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount'); } @@ -17497,9 +17299,6 @@ function baseCreateRenderer(options, createHydrationFns) { queuePostRenderEffect(a, parentSuspense); } instance.isMounted = true; - if ( __VUE_PROD_DEVTOOLS__) { - devtoolsComponentAdded(instance); - } // #2458: deference mount-only object parameters to prevent memleaks initialVNode = container = anchor = null; } @@ -17550,9 +17349,6 @@ function baseCreateRenderer(options, createHydrationFns) { invokeVNodeHook(vnodeHook, parent, next, vnode); }, parentSuspense); } - if ( __VUE_PROD_DEVTOOLS__) { - devtoolsComponentUpdated(instance); - } } }, prodEffectOptions); }; @@ -18006,9 +17802,6 @@ function baseCreateRenderer(options, createHydrationFns) { parentSuspense.resolve(); } } - if ( __VUE_PROD_DEVTOOLS__) { - devtoolsComponentRemoved(instance); - } }; const unmountChildren = (children, parentComponent, parentSuspense, doRemove = false, optimized = false, start = 0) => { for (let i = start; i < children.length; i++) { @@ -18884,10 +18677,10 @@ const publicPropertiesMap = extend(Object.create(null), { $parent: i => getPublicInstance(i.parent), $root: i => getPublicInstance(i.root), $emit: i => i.emit, - $options: i => (__VUE_OPTIONS_API__ ? resolveMergedOptions(i) : i.type), + $options: i => ( resolveMergedOptions(i) ), $forceUpdate: i => () => queueJob(i.update), $nextTick: i => nextTick.bind(i.proxy), - $watch: i => (__VUE_OPTIONS_API__ ? instanceWatch.bind(i) : NOOP) + $watch: i => ( instanceWatch.bind(i) ) }); const PublicInstanceProxyHandlers = { get({ _: instance }, key) { @@ -18938,7 +18731,7 @@ const PublicInstanceProxyHandlers = { accessCache[key] = 3 /* CONTEXT */; return ctx[key]; } - else if (!__VUE_OPTIONS_API__ || shouldCacheAccess) { + else if ( shouldCacheAccess) { accessCache[key] = 4 /* OTHER */; } } @@ -19160,11 +18953,6 @@ function handleSetupResult(instance, setupResult, isSSR) { } } else if (isObject(setupResult)) { - // setup returned bindings. - // assuming a render function compiled from template is present. - if ( __VUE_PROD_DEVTOOLS__) { - instance.devtoolsRawSetupState = setupResult; - } instance.setupState = proxyRefs(setupResult); } else ; @@ -19183,7 +18971,7 @@ function finishComponentSetup(instance, isSSR) { } } // support for 2.x options - if (__VUE_OPTIONS_API__) { + { currentInstance = instance; pauseTracking(); applyOptions(instance, Component);