diff --git a/examples/_static/index.html b/examples/_static/index.html index a1704e2..c9c923a 100644 --- a/examples/_static/index.html +++ b/examples/_static/index.html @@ -7,15 +7,15 @@

Vue Meta Examples

diff --git a/examples/meta-loader.js b/examples/meta-loader.js new file mode 100644 index 0000000..3469b55 --- /dev/null +++ b/examples/meta-loader.js @@ -0,0 +1,75 @@ +const { + baseParse, + transform, + generate, + processIf, + getBaseTransformPreset, + createObjectExpression, + createObjectProperty, +} = require('@vue/compiler-core') + +const { parse } = require('@vue/compiler-dom') + +function headTransform(node, context) { + console.log('NODE', node) + if (node.type === 1 /* NodeTypes.ELEMENT */) { + return () => { + if (!context.parent.codegenNode) { + context.parent.codegenNode = createObjectExpression([]) + } + + const options = context.parent.codegenNode + const option = createObjectProperty( + node.tag, + node.children.length === 1 ? node.children[0] : 'null' + ) + + //options.properties.push(option) + } + } +} + +module.exports = function (source, map) { + // TODO: add options + const ast = parse(source) +//console.log('AST', ast) + + const [nodeTransforms, directiveTransforms] = getBaseTransformPreset({ + prefixIdentifiers: true + }) + + transform(ast, { + prefixIdentifiers: true, + nodeTransforms: [ + ...nodeTransforms, + headTransform + ], + directiveTransforms + }) + + const result = generate(ast, { mode: 'module' }) + +console.log(result.code) + + this.callback(null, ` +import { computed } from 'vue' + +${result.code} +export default function (component) { + const setup = component.setup + + component.setup = function (...args) { + console.log(component) + const __htmlMetaData = computed(() => { + + }) + + return { + ...setup.apply(this, args), + __htmlMetaData + } + } + +}`, map) + /**/ +} diff --git a/examples/next/index.js b/examples/next/index.js new file mode 100644 index 0000000..6b59b25 --- /dev/null +++ b/examples/next/index.js @@ -0,0 +1,4 @@ + +export default { + +} diff --git a/examples/package.json b/examples/package.json index c4f419d..4cf5989 100644 --- a/examples/package.json +++ b/examples/package.json @@ -20,28 +20,29 @@ }, "homepage": "https://github.com/nuxt/vue-meta#readme", "devDependencies": { - "@babel/core": "^7.6.0", - "@babel/node": "^7.6.1", - "@babel/plugin-syntax-dynamic-import": "^7.2.0", - "@babel/preset-env": "^7.6.0", - "babel-loader": "^8.0.6", + "@babel/core": "^7.9.0", + "@babel/node": "^7.8.7", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/preset-env": "^7.9.0", + "@vue/compiler-sfc": "^3.0.0-alpha.10", + "@vue/server-renderer": "^3.0.0-alpha.10", + "babel-loader": "^8.1.0", "babel-plugin-dynamic-import-node": "^2.3.0", - "consola": "^2.10.1", + "consola": "^2.11.3", "core-js": "3", - "cross-env": "^5.2.1", + "cross-env": "^7.0.2", "express": "^4.17.1", "express-urlrewrite": "^1.2.0", - "fs-extra": "^8.1.0", + "fs-extra": "^9.0.0", "lodash": "^4.17.15", - "vue": "^2.6.10", - "vue-loader": "^15.7.1", - "vue-meta": "^2.2.2", - "vue-router": "^3.1.3", - "vue-server-renderer": "^2.6.10", - "vue-template-compiler": "^2.6.10", - "vuex": "^3.1.1", - "webpack": "^4.39.3", - "webpack-dev-server": "^3.8.0", + "vue": "next", + "vue-loader": "next", + "vue-meta": "^2.3.3", + "vue-router": "next", + "vue-template-compiler": "^2.6.11", + "vuex": "^3.1.3", + "webpack": "^4.42.1", + "webpack-dev-server": "^3.10.3", "webpackbar": "^4.0.0" } } diff --git a/examples/server.js b/examples/server.js index 170af38..a771d1a 100644 --- a/examples/server.js +++ b/examples/server.js @@ -12,7 +12,7 @@ const app = express() app.use(webpackDevMiddleware(webpack(WebpackConfig), { publicPath: '/__build__/', - writeToDisk: false, + writeToDisk: true, stats: { colors: true, chunks: false diff --git a/examples/ssr/App.js b/examples/ssr/App.js index 867eb04..5c9a839 100644 --- a/examples/ssr/App.js +++ b/examples/ssr/App.js @@ -1,13 +1,13 @@ -import Vue from 'vue' -import Router from 'vue-router' +import { createSSRApp } from 'vue' +import { createRouter, createMemoryHistory } from 'vue-router' import VueMeta from '../../' -Vue.use(Router) +/*Vue.use(Router) Vue.use(VueMeta, { tagIDKeyName: 'hid' -}) +})*/ -export default function createApp () { +export default function createMyApp () { const Home = { template: `
About @@ -54,16 +54,15 @@ export default function createApp () { } } - const router = new Router({ - mode: 'history', - base: '/ssr', + const router = createRouter({ + history: createMemoryHistory('/ssr'), routes: [ { path: '/', component: Home }, { path: '/about', component: About } ] }) - const app = new Vue({ + const app = createSSRApp({ router, metaInfo () { return { @@ -145,13 +144,16 @@ export default function createApp () {
` + }) - const { set } = app.$meta().addApp('custom') + app.use(router) + + /*const { set } = app.$meta().addApp('custom') set({ bodyAttrs: { class: 'custom-app' }, meta: [{ charset: 'utf-8' }] - }) + })*/ return { app, router } } diff --git a/examples/ssr/browser.js b/examples/ssr/browser.js index 37a7e49..974aaf1 100644 --- a/examples/ssr/browser.js +++ b/examples/ssr/browser.js @@ -3,4 +3,4 @@ import createApp from './App' window.users = [] const { app } = createApp() -app.$mount('#app') +app.mount('#app') diff --git a/examples/ssr/server.js b/examples/ssr/server.js index d7334db..4369845 100644 --- a/examples/ssr/server.js +++ b/examples/ssr/server.js @@ -1,11 +1,9 @@ import path from 'path' import fs from 'fs-extra' import template from 'lodash/template' -import { createRenderer } from 'vue-server-renderer' +const { renderToString } = require('@vue/server-renderer') import createApp from './App' -const renderer = createRenderer({ runInNewContext: false }) - const templateFile = path.resolve(__dirname, 'app.template.html') const templateContent = fs.readFileSync(templateFile, { encoding: 'utf8' }) @@ -17,24 +15,34 @@ process.server = true export async function renderPage ({ url }) { const { app, router } = await createApp() - router.push(url.substr(4)) + await router.push(url.substr(4)) - return new Promise((resolve, reject) => { - router.onReady(async () => { - const matchedComponents = router.getMatchedComponents() - // no matched routes, reject with 404 - if (!matchedComponents.length) { - return reject({ code: 404 }) - } + await router.isReady() + /*console.log(router) + const matchedComponents = router.getMatchedComponents() + // no matched routes, reject with 404 + if (!matchedComponents.length) { + return reject({ code: 404 }) + }*/ - const appHtml = await renderer.renderToString(app) + const appHtml = await renderToString(app) - const pageHtml = compiled({ - app: appHtml, - ...app.$meta().inject() - }) - - resolve(pageHtml) - }) + const pageHtml = compiled({ + app: appHtml, + htmlAttrs: { + text: () => {} + }, + headAttrs: { + text: () => {} + }, + bodyAttrs: { + text: () => {} + }, + head: () => {}, + bodyPrepend: () => {}, + bodyAppend: () => {} + //...app.$meta().inject() }) + + return pageHtml } diff --git a/examples/vue-router/about.vue b/examples/vue-router/about.vue new file mode 100644 index 0000000..fe2c414 --- /dev/null +++ b/examples/vue-router/about.vue @@ -0,0 +1,30 @@ + + + + {{ title }} + + + + + +useMeta() diff --git a/examples/vue-router/app.js b/examples/vue-router/app.js index 8355d92..58c490d 100644 --- a/examples/vue-router/app.js +++ b/examples/vue-router/app.js @@ -1,16 +1,18 @@ -import Vue from 'vue' +import { createApp, defineComponent, reactive, toRefs, h } from 'vue' import VueMeta from 'vue-meta' -import Router from 'vue-router' +import { createRouter, createWebHistory } from 'vue-router' +import About from './about.vue' -Vue.use(Router) -Vue.use(VueMeta, { +/*Vue.use(VueMeta, { refreshOnceOnNavigation: true -}) +})*/ let metaUpdated = 'no' -const ChildComponent = { +const ChildComponent = defineComponent({ name: 'child-component', - props: ['page'], + props: { + page: String + }, template: `

You're looking at the {{ page }} page

Has metaInfo been updated due to navigation? {{ metaUpdated }}

@@ -26,21 +28,25 @@ const ChildComponent = { } } }, - data () { - return { + setup () { + const state = reactive({ date: null, metaUpdated + }) + + return { + ...toRefs(state) } }, - mounted () { + /*mounted () { this.interval = setInterval(() => { this.date = new Date() }, 1000) }, destroyed () { clearInterval(this.interval) - } -} + }*/ +}) // this wrapper function is not a requirement for vue-router, // just a demonstration that render-function style components also work. @@ -48,25 +54,21 @@ const ChildComponent = { function view (page) { return { name: `section-${page}`, - render (h) { - return h(ChildComponent, { - props: { page } - }) + render () { + return h(ChildComponent, { page }) } } } -const router = new Router({ - mode: 'history', - base: '/vue-router', +const router = createRouter({ + history: createWebHistory('/vue-router'), routes: [ - { path: '/', component: view('home') }, - { path: '/about', component: view('about') } + { name: 'home', path: '/', component: view('home') }, + { name: 'about', path: '/about', component: About } ] }) const App = { - router, template: `

vue-router

@@ -80,8 +82,10 @@ const App = { ` } -const app = new Vue(App) +const app = createApp(App) +app.use(router) +/* const { set, remove } = app.$meta().addApp('custom') set({ @@ -93,8 +97,8 @@ set({ ] }) setTimeout(() => remove(), 3000) - -app.$mount('#app') +*/ +app.mount('#app') /* const waitFor = time => new Promise(r => setTimeout(r, time || 1000)) diff --git a/examples/webpack.config.js b/examples/webpack.config.js index 2f85f4c..b358c18 100644 --- a/examples/webpack.config.js +++ b/examples/webpack.config.js @@ -2,7 +2,7 @@ import fs from 'fs' import path from 'path' import webpack from 'webpack' import WebpackBar from 'webpackbar' -import VueLoaderPlugin from 'vue-loader/lib/plugin' +import { VueLoaderPlugin } from 'vue-loader' const srcDir = path.join(__dirname, '..', 'src') @@ -15,7 +15,7 @@ export default { if (dir === 'ssr') { entries[dir] = path.join(fullDir, 'browser.js') - } else { + } else if (dir === 'vue-router') { const entry = path.join(fullDir, 'app.js') if (fs.statSync(fullDir).isDirectory() && fs.existsSync(entry)) { entries[dir] = entry @@ -47,13 +47,24 @@ export default { } } }, - { test: /\.vue$/, use: 'vue-loader' } + { + resourceQuery: /blockType=head/, + loader: require.resolve('./meta-loader.js') + }, + { + test: /\.vue$/, + use: 'vue-loader' + } ] }, resolve: { alias: { - 'vue': 'vue/dist/vue.js', - 'vue-meta': process.env.NODE_ENV === 'development' ? srcDir : 'vue-meta' + // this isn't technically needed, since the default `vue` entry for bundlers + // is a simple `export * from '@vue/runtime-dom`. However having this + // extra re-export somehow causes webpack to always invalidate the module + // on the first HMR update and causes the page to reload. + 'vue': 'vue/dist/vue.esm.js', + 'vue-meta': path.resolve(__dirname, './next/') } }, // Expose __dirname to allow automatically setting basename. @@ -67,5 +78,12 @@ export default { new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development') }) - ] + ], + devServer: { + inline: true, + hot: true, + stats: 'minimal', + contentBase: __dirname, + overlay: true + } } diff --git a/package.json b/package.json index 88f92d8..60e29f2 100644 --- a/package.json +++ b/package.json @@ -114,11 +114,10 @@ "standard-version": "^7.1.0", "tib": "^0.7.4", "typescript": "^3.8.3", - "vue": "^2.6.11", + "vue": "^3.0.0-alpha.10", "vue-jest": "^3.0.5", "vue-loader": "^15.9.1", "vue-router": "^3.1.6", - "vue-server-renderer": "^2.6.11", "vue-template-compiler": "^2.6.11", "vuepress": "^1.4.0", "vuepress-theme-vue": "^1.1.0", diff --git a/yarn.lock b/yarn.lock index 2664c1a..e8a2c50 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1855,6 +1855,25 @@ "@vue/babel-plugin-transform-vue-jsx" "^1.1.2" camelcase "^5.0.0" +"@vue/compiler-core@3.0.0-alpha.10": + version "3.0.0-alpha.10" + resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.0.0-alpha.10.tgz#39e8de2d7fe8a932cd08958200f37086a9d6841a" + integrity sha512-YXJJyFfkgmX3Rnf+sEcL8RR9a9UiHqB6ng1pzN1Dy8STASqUBdwinvi/xBuuCS7mDls12xn562y5CEATAwZs/Q== + dependencies: + "@babel/parser" "^7.8.6" + "@babel/types" "^7.8.6" + "@vue/shared" "3.0.0-alpha.10" + estree-walker "^0.8.1" + source-map "^0.6.1" + +"@vue/compiler-dom@3.0.0-alpha.10": + version "3.0.0-alpha.10" + resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.0.0-alpha.10.tgz#be9ec1d24d0c4d96d164f8e00a479bd88a45e55d" + integrity sha512-hOasMBUsmqccY9Qyytqmrup4AnxQ6zBHT8tC9QpfdtygvxrFK2uNvNZlPoZay2hB13fJjZgRdCyxELM0zB4Hww== + dependencies: + "@vue/compiler-core" "3.0.0-alpha.10" + "@vue/shared" "3.0.0-alpha.10" + "@vue/component-compiler-utils@^3.1.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@vue/component-compiler-utils/-/component-compiler-utils-3.1.0.tgz#64cd394925f5af1f9c3228c66e954536f5311857" @@ -1870,6 +1889,30 @@ source-map "~0.6.1" vue-template-es2015-compiler "^1.9.0" +"@vue/reactivity@3.0.0-alpha.10": + version "3.0.0-alpha.10" + resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.0.0-alpha.10.tgz#d859acd384e42d42086cfefbefe478825aaa9b82" + integrity sha512-H4E0kbQQuc9W0eVKkPLK5g1CwUQkMh4pUWEE/Gl2pZsnDVNJlvbZIMwKu6P5cjd30Nnbv2sG3+wcUGS4TplDuA== + dependencies: + "@vue/shared" "3.0.0-alpha.10" + +"@vue/runtime-core@3.0.0-alpha.10": + version "3.0.0-alpha.10" + resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.0.0-alpha.10.tgz#abba11b4c8ed4933632050c0319f63fffe66bb86" + integrity sha512-b4YPU+DnowcthtcZSPgAxEExAq/dz31aQasiY1lvSB54y4T2QNYOydVYnZsFUMOFhN0Fh3+k5s1dTolorem1cw== + dependencies: + "@vue/reactivity" "3.0.0-alpha.10" + "@vue/shared" "3.0.0-alpha.10" + +"@vue/runtime-dom@3.0.0-alpha.10": + version "3.0.0-alpha.10" + resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.0.0-alpha.10.tgz#005880179a52001b4e4e76c816555cc0ce5d16a9" + integrity sha512-X0UcZlXBwZ0OW4yw3hA+8uE2CArPDf2LKk9aTIi3xrCeluQmJSEUsgDNxHBqvmNhVGqdi0kPB09NrOxfEtyPhw== + dependencies: + "@vue/runtime-core" "3.0.0-alpha.10" + "@vue/shared" "3.0.0-alpha.10" + csstype "^2.6.8" + "@vue/server-test-utils@^1.0.0-beta.30": version "1.0.0-beta.30" resolved "https://registry.yarnpkg.com/@vue/server-test-utils/-/server-test-utils-1.0.0-beta.30.tgz#960a6383de81ba5ff763bdd6e961b9443e98fa82" @@ -1878,6 +1921,11 @@ "@types/cheerio" "^0.22.10" cheerio "^1.0.0-rc.2" +"@vue/shared@3.0.0-alpha.10": + version "3.0.0-alpha.10" + resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.0.0-alpha.10.tgz#7026d9a81fa5f03ea03e9434be6286ed167684b8" + integrity sha512-b6VYQrhsp/N0QpuXdxs1xIDrBiqVzFNyAvyQgPk2ssQgWD6H2StoySDj99DWrum2+pJUDO2/2dLfGH8l180R6g== + "@vue/test-utils@^1.0.0-beta.30": version "1.0.0-beta.30" resolved "https://registry.yarnpkg.com/@vue/test-utils/-/test-utils-1.0.0-beta.30.tgz#d5f26d1e2411fdb7fa7fdedb61b4b4ea4194c49d" @@ -4469,6 +4517,11 @@ cssstyle@^2.2.0: dependencies: cssom "~0.3.6" +csstype@^2.6.8: + version "2.6.9" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.9.tgz#05141d0cd557a56b8891394c1911c40c8a98d098" + integrity sha512-xz39Sb4+OaTsULgUERcCk+TJj8ylkL4aSVDQiX/ksxbELSqwkgt4d4RD7fovIdgJGSuNYqwZEiVjYY5l0ask+Q== + currently-unhandled@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" @@ -5460,6 +5513,11 @@ estree-walker@^0.6.1: resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.6.1.tgz#53049143f40c6eb918b23671d1fe3219f3a1b362" integrity sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w== +estree-walker@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.8.1.tgz#6230ce2ec9a5cb03888afcaf295f97d90aa52b79" + integrity sha512-H6cJORkqvrNziu0KX2hqOMAlA2CiuAxHeGJXSIoKA/KLv229Dw806J3II6mKTm5xiDX1At1EXCfsOQPB+tMB+g== + esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" @@ -12674,7 +12732,7 @@ vue-router@^3.1.6: resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.1.6.tgz#45f5a3a3843e31702c061dd829393554e4328f89" integrity sha512-GYhn2ynaZlysZMkFE5oCHRUTqE8BWs/a9YbKpNLi0i7xD6KG1EzDqpHQmv1F5gXjr8kL5iIVS8EOtRaVUEXTqA== -vue-server-renderer@^2.6.10, vue-server-renderer@^2.6.11: +vue-server-renderer@^2.6.10: version "2.6.11" resolved "https://registry.yarnpkg.com/vue-server-renderer/-/vue-server-renderer-2.6.11.tgz#be8c9abc6aacc309828a755c021a05fc474b4bc3" integrity sha512-V3faFJHr2KYfdSIalL+JjinZSHYUhlrvJ9pzCIjjwSh77+pkrsXpK4PucdPcng57+N77pd1LrKqwbqjQdktU1A== @@ -12709,11 +12767,20 @@ vue-template-es2015-compiler@^1.6.0, vue-template-es2015-compiler@^1.9.0: resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825" integrity sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw== -vue@^2.6.10, vue@^2.6.11: +vue@^2.6.10: version "2.6.11" resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.11.tgz#76594d877d4b12234406e84e35275c6d514125c5" integrity sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ== +vue@^3.0.0-alpha.10: + version "3.0.0-alpha.10" + resolved "https://registry.yarnpkg.com/vue/-/vue-3.0.0-alpha.10.tgz#0f1cb5471edc41e0b0153ff07f462e376e03b0ae" + integrity sha512-USdgVs1bQfuiM5ivt2S2XGKOmDC+gKhhc3RNKjASUnh9kWv/vhNJlQiqIaUFiPN9SE9833fWy3PKOJFj9yZjPQ== + dependencies: + "@vue/compiler-dom" "3.0.0-alpha.10" + "@vue/runtime-dom" "3.0.0-alpha.10" + "@vue/shared" "3.0.0-alpha.10" + vuepress-html-webpack-plugin@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/vuepress-html-webpack-plugin/-/vuepress-html-webpack-plugin-3.2.0.tgz#219be272ad510faa8750d2d4e70fd028bfd1c16e"