From 9cfde5b5509e7cd0899ea450801bed753ec64075 Mon Sep 17 00:00:00 2001 From: pimlie Date: Mon, 25 Jan 2021 00:50:46 +0100 Subject: [PATCH] feat: make ssr work feat: update build script chore: use jiti instead of babel-node for examples --- .eslintrc | 3 +- LICENSE.md | 5 +- babel.config.js | 43 -- build/rollup.config.js | 157 ++++ build/stub.js | 1 + examples/README.md | 42 -- examples/_static/user-1.js | 5 + examples/_static/user-2.js | 5 + examples/_static/user-3.js | 5 + examples/_static/user-4.js | 5 + examples/jiti.js | 45 ++ examples/meta-loader.js.not-used | 76 -- examples/server.js | 23 +- examples/ssr/app.template.html | 12 +- examples/ssr/server.js | 39 +- examples/vue-router/App.js | 25 +- examples/vue-router/index.html | 2 +- examples/vue-router/main.js | 4 +- examples/webpack.config.js | 158 ++-- jest.config.js | 4 +- package.json | 58 +- scripts/rollup.config.js | 181 ----- scripts/update-cdn.js | 36 - src/Metainfo.ts | 62 +- src/global.d.ts | 1 + src/index.ts | 12 +- src/install.ts | 17 - src/manager.ts | 112 ++- src/object-merge/index.ts | 1 + src/object-merge/proxy.ts | 10 +- src/render.ts | 34 +- src/ssr.ts | 29 + src/types/index.ts | 30 +- src/useApi.ts | 3 +- test/unit/render.test.js | 4 +- tsconfig.json | 2 +- yarn.lock | 1180 ++++++------------------------ 37 files changed, 825 insertions(+), 1606 deletions(-) delete mode 100644 babel.config.js create mode 100644 build/rollup.config.js create mode 100644 build/stub.js delete mode 100644 examples/README.md create mode 100644 examples/jiti.js delete mode 100644 examples/meta-loader.js.not-used delete mode 100644 scripts/rollup.config.js delete mode 100644 scripts/update-cdn.js delete mode 100644 src/install.ts create mode 100644 src/ssr.ts diff --git a/.eslintrc b/.eslintrc index 9078c4a..f44d9c9 100644 --- a/.eslintrc +++ b/.eslintrc @@ -3,7 +3,8 @@ "@nuxtjs/eslint-config-typescript" ], "globals": { - "__DEV__": true + "__DEV__": true, + "__BROWSER__": false, }, "overrides": [ { diff --git a/LICENSE.md b/LICENSE.md index eddb309..0ac8d28 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,9 +1,6 @@ MIT License -Copyright (c) 2016-2019 -- Declan de Wet -- Sébastien Chopin -- All the amazing contributors (https://github.com/nuxt/vue-meta/graphs/contributors) +Copyright (c) 2021 - Pim (@pimlie) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/babel.config.js b/babel.config.js deleted file mode 100644 index e11ed42..0000000 --- a/babel.config.js +++ /dev/null @@ -1,43 +0,0 @@ -const path = require('path') - -module.exports = { - presets: [ - ['@babel/preset-env', { - useBuiltIns: 'usage', - corejs: 3, - targets: { - ie: 9 - } - }], - '@babel/preset-typescript', - ], - plugins: [ - 'dynamic-import-node', - ['global-define', { - '__DEV__': 'true' - }], - ['module-resolver', { - root: '.', - extensions: ['.ts'], - alias: { - 'vue-meta': path.resolve('./src/') - } - }], - ], - env: { - test: { - plugins: [ - '@babel/plugin-syntax-dynamic-import', - 'dynamic-import-node' - ], - presets: [ - [ '@babel/preset-env', { - targets: { - node: 'current' - } - }], - '@babel/preset-typescript' - ], - } - } -} diff --git a/build/rollup.config.js b/build/rollup.config.js new file mode 100644 index 0000000..7baedf6 --- /dev/null +++ b/build/rollup.config.js @@ -0,0 +1,157 @@ +import path from 'path' +import alias from '@rollup/plugin-alias' +// import babel from '@rollup/plugin-babel' +import commonjs from '@rollup/plugin-commonjs' +import nodeResolve from '@rollup/plugin-node-resolve' +import replace from '@rollup/plugin-replace' +import { terser } from 'rollup-plugin-terser' +import ts from 'rollup-plugin-typescript2' +import defaultsDeep from 'lodash/defaultsDeep' + +const pkg = require('../package.json') + +const banner = `/** + * ${pkg.name} v${pkg.version} + * (c) ${new Date().getFullYear()} + * - Pim (@pimlie) + * - All the amazing contributors + * @license MIT + */ +` + +let didTS = false + +function rollupConfig({ + plugins = [], + external = [], + ...config + }) { + + const isBrowserBuild = !config.output || !config.output.format || config.output.format === 'iife' || config.output.file.includes('-browser.') + const isProductionBuild = config.output.file.includes('.prod.') + + const replaceConfig = { + exclude: 'node_modules', + delimiters: ['', ''], + values: { + 'process.server' : isBrowserBuild ? 'false' : 'true', // should not be used anymore + '__DEV__': config.output.format === 'es' && !isBrowserBuild ? "(process.env.NODE_ENV !== 'production')" : !isProductionBuild, + '__BROWSER__': isBrowserBuild, + } + } + + if (isBrowserBuild) { + external = ['vue'] + } else { + external = Object.keys(pkg.peerDependencies) + external.push('@vue/server-renderer') + } + + const thisConfig = defaultsDeep({}, config, { + input: 'src/index.ts', + output: { + name: 'VueMeta', + format: 'iife', + sourcemap: false, + banner, + externalLiveBindings: false, + globals: { + vue: 'Vue' + } + }, + external, + plugins: [ + replace(replaceConfig), + nodeResolve(), + commonjs(), + ts({ + check: !didTS, + tsconfig: path.resolve(__dirname, '../tsconfig.json'), + cacheRoot: path.resolve(__dirname, '../node_modules/.rts2_cache'), + tsconfigOverride: { + compilerOptions: { + sourceMap: true, + declaration: !didTS, + declarationMap: !didTS, + }, + exclude: ['__tests__', 'test-dts'], + }, + }), + ].concat(plugins), + }) + + if (isBrowserBuild) { + // remove the ssr renderToString helper for browser builds + thisConfig.plugins.unshift(alias({ + entries: [ + { find: '.\/ssr', replacement: path.resolve(__dirname, './stub.js') }, + ] + })) + } + + if (config.output.file.includes('.min.')) { + const terserOpts = { + module: config.output.format === 'es', + compress: { + ecma: 2015, + pure_getters: true, + }, + } + + thisConfig.plugins.push(terser(terserOpts)) + } + + didTS = true + + return thisConfig +} + +export default [ + // umd web build + { + output: { + file: pkg.unpkg, + }, + }, + // minimized umd web build + { + output: { + file: pkg.unpkg.replace('.js', '.min.js'), + }, + }, + // common js build + { + output: { + file: pkg.main, + format: 'cjs' + }, + }, + // common js build + { + output: { + file: pkg.main.replace('.js', '.prod.js'), + format: 'cjs' + }, + }, + // esm build + { + output: { + file: pkg.module, + format: 'es' + }, + }, + // browser esm build + { + output: { + file: pkg.module.replace('-bundler.js', '-browser.js'), + format: 'es' + }, + }, + // minimized browser esm build + { + output: { + file: pkg.module.replace('-bundler.js', '-browser.min.js'), + format: 'es' + }, + } +].map(rollupConfig) diff --git a/build/stub.js b/build/stub.js new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/build/stub.js @@ -0,0 +1 @@ + diff --git a/examples/README.md b/examples/README.md deleted file mode 100644 index 589668b..0000000 --- a/examples/README.md +++ /dev/null @@ -1,42 +0,0 @@ -# Vue Meta Examples - -## Prepare examples - -To prepare the examples to run locally, please follow these steps: - -```bash -git clone https://github.com/nuxt/vue-meta -cd examples -yarn install -``` - -## Run the examples - -When the examples are installed locally, start the example server as follows - -```js -yarn start -// or -HOST=0.0.0.0 PORT=8080 yarn start -``` -and browse to `http://localhost:3000` or whatever you changed the host and port to - -### SSR Example - -The server side rendering example is available on the cli only, to run the SSR example just run - -```bash -yarn ssr -``` - -## Developing - -If you would like to use the examples while developing or debugging `vue-meta` features or issues, please do as follows - -```js -git clone https://github.com/nuxt/vue-meta -yarn install -cd examples -yarn install -yarn dev -``` diff --git a/examples/_static/user-1.js b/examples/_static/user-1.js index 6908ddd..6f6df9b 100644 --- a/examples/_static/user-1.js +++ b/examples/_static/user-1.js @@ -1,3 +1,8 @@ +if (!window.users) { + window.users = [] + console.warn('window.users was not set') +} + window.users.push({ id: 1, name: 'Leanne Graham', diff --git a/examples/_static/user-2.js b/examples/_static/user-2.js index f17f67d..c22509f 100644 --- a/examples/_static/user-2.js +++ b/examples/_static/user-2.js @@ -1,3 +1,8 @@ +if (!window.users) { + window.users = [] + console.warn('window.users was not set') +} + window.users.push({ id: 2, name: 'Ervin Howell', diff --git a/examples/_static/user-3.js b/examples/_static/user-3.js index cd00e42..abb71ab 100644 --- a/examples/_static/user-3.js +++ b/examples/_static/user-3.js @@ -1,3 +1,8 @@ +if (!window.users) { + window.users = [] + console.warn('window.users was not set') +} + window.users.push({ id: 3, name: 'Clementine Bauch', diff --git a/examples/_static/user-4.js b/examples/_static/user-4.js index 7084433..87a7e2c 100644 --- a/examples/_static/user-4.js +++ b/examples/_static/user-4.js @@ -1,3 +1,8 @@ +if (!window.users) { + window.users = [] + console.warn('window.users was not set') +} + window.users.push({ id: 4, name: 'Patricia Lebsack', diff --git a/examples/jiti.js b/examples/jiti.js new file mode 100644 index 0000000..24e7ba8 --- /dev/null +++ b/examples/jiti.js @@ -0,0 +1,45 @@ +const path = require('path') +const { transformSync } = require('@babel/core') + +module.exports = require('jiti')(__filename, { + cache: false, + debug: false, + transform (opts) { + const _opts = { + babelrc: false, + configFile: false, + compact: false, + retainLines: typeof opts.retainLines === 'boolean' ? opts.retainLines : true, + filename: '', + cwd: '/', + plugins: [ + [require('@babel/plugin-transform-modules-commonjs'), { allowTopLevelThis: true }], + [require('@babel/plugin-transform-typescript')], + [require('babel-plugin-dynamic-import-node'), { noInterop: true }], + [require('babel-plugin-global-define'), { + __DEV__: true, + __BROWSER__: false + }], + [require('babel-plugin-module-resolver'), { + root: '.', + extensions: ['.ts'], + alias: { + 'vue-meta': path.resolve(__dirname, '../src/') + } + }] + ] + } + + try { + return transformSync(opts.source, _opts).code || '' + } catch (err) { + return 'exports.__JITI_ERROR__ = ' + JSON.stringify({ + filename: opts.filename, + line: (err.loc && err.loc.line) || 0, + column: (err.loc && err.loc.column) || 0, + code: err.code && err.code.replace('BABEL_', '').replace('PARSE_ERROR', 'ParseError'), + message: err.message.replace('/: ', '').replace(/\(.+\)\s*$/, '') + }) + } + } +}) diff --git a/examples/meta-loader.js.not-used b/examples/meta-loader.js.not-used deleted file mode 100644 index fa10731..0000000 --- a/examples/meta-loader.js.not-used +++ /dev/null @@ -1,76 +0,0 @@ -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/server.js b/examples/server.js index c52bcd0..30be340 100644 --- a/examples/server.js +++ b/examples/server.js @@ -1,17 +1,20 @@ -import fs from 'fs' -import path from 'path' -import consola from 'consola' -import express from 'express' -import rewrite from 'express-urlrewrite' -import webpack from 'webpack' -import webpackDevMiddleware from 'webpack-dev-middleware' -import WebpackConfig from './webpack.config' -import { renderPage } from './ssr/server' +const fs = require('fs') +const path = require('path') +const consola = require('consola') +const express = require('express') +const rewrite = require('express-urlrewrite') +const webpack = require('webpack') +const webpackDevMiddleware = require('webpack-dev-middleware') +const webpackConfig = require('./webpack.config') +const jiti = require('./jiti') + +const { renderPage } = jiti('./ssr/server.js') +// const { renderPage } = require('./ssr/server') const app = express() app.use( - webpackDevMiddleware(webpack(WebpackConfig), { + webpackDevMiddleware(webpack(webpackConfig(true)), { publicPath: '/__build__/', writeToDisk: true, stats: { diff --git a/examples/ssr/app.template.html b/examples/ssr/app.template.html index 10a996c..42b4d4a 100644 --- a/examples/ssr/app.template.html +++ b/examples/ssr/app.template.html @@ -1,16 +1,16 @@ - - - {{ head(true) }} + + + {{ head }} - - {{ bodyPrepend(true) }} + + {{ bodyPrepend }} ← Examples index {{ app }} - {{ bodyAppend(true) }} + {{ bodyAppend }} diff --git a/examples/ssr/server.js b/examples/ssr/server.js index baabd26..e743948 100644 --- a/examples/ssr/server.js +++ b/examples/ssr/server.js @@ -1,8 +1,9 @@ import path from 'path' import fs from 'fs-extra' import { createSSRApp } from 'vue' +import { renderToStringWithMeta } from 'vue-meta' + import template from 'lodash/template' -import { renderToString } from '@vue/server-renderer' import { App, createRouter, metaManager } from '../vue-router/main' const templateFile = path.resolve(__dirname, 'app.template.html') @@ -15,41 +16,31 @@ process.server = true export async function renderPage ({ url }) { console.log('renderPage', url) + const app = createSSRApp(App) const router = createRouter('/ssr', true) app.use(router) - // app.use(metaManager) + app.use(metaManager) - console.log('renderPage', 'push') await router.push(url.substr(4)) await router.isReady() - console.log('renderPage', 'eady') - /* console.log(router) - const matchedComponents = router.getMatchedComponents() - // no matched routes, reject with 404 - if (!matchedComponents.length) { - return reject({ code: 404 }) - } */ - const appHtml = await renderToString(app) + const [appHtml, ctx] = await renderToStringWithMeta(app) + + if (!ctx.teleports) { + ctx.teleports = {} + } const pageHtml = compiled({ app: appHtml, - htmlAttrs: { - text: () => {} - }, - headAttrs: { - text: () => {} - }, - bodyAttrs: { - text: () => {} - }, - head: () => {}, - bodyPrepend: () => {}, - bodyAppend: () => {} - // ...app.$meta().inject() + htmlAttrs: ctx.teleports.htmlAttrs || '', + headAttrs: ctx.teleports.headAttrs || '', + bodyAttrs: ctx.teleports.bodyAttrs || '', + head: ctx.teleports.head || '', + bodyPrepend: ctx.teleports['body-prepend'] || '', + bodyAppend: ctx.teleports.body || '' }) return pageHtml diff --git a/examples/vue-router/App.js b/examples/vue-router/App.js index 7965068..f34676f 100644 --- a/examples/vue-router/App.js +++ b/examples/vue-router/App.js @@ -29,7 +29,7 @@ export default { { tag: 'link', rel: 'stylesheet', href: 'style2.css' } ] }, - body: 'body-script1.js', + body: 'body-script1.js', // TODO: fix htmlAttrs: { amp: true, lang: ['en', 'nl'] @@ -44,7 +44,7 @@ export default { // TODO { content: 'window.a = "
"; diff --git a/examples/vue-router/main.js b/examples/vue-router/main.js index 246f2a2..d792684 100644 --- a/examples/vue-router/main.js +++ b/examples/vue-router/main.js @@ -1,6 +1,6 @@ import { h } from 'vue' import { createRouter as createVueRouter, createMemoryHistory, createWebHistory } from 'vue-router' -import { createManager, defaultConfig, resolveOption, useMeta } from 'vue-meta' +import { createMetaManager, defaultConfig, resolveOption, useMeta } from 'vue-meta' import App from './App' import ChildComponent from './Child' @@ -20,7 +20,7 @@ const decisionMaker5000000 = resolveOption((prevValue, context) => { } }) -const metaManager = createManager({ +const metaManager = createMetaManager({ ...defaultConfig, esi: { group: true, diff --git a/examples/webpack.config.js b/examples/webpack.config.js index f349baf..77abb0b 100644 --- a/examples/webpack.config.js +++ b/examples/webpack.config.js @@ -1,89 +1,93 @@ -import fs from 'fs' -import path from 'path' -import webpack from 'webpack' -import WebpackBar from 'webpackbar' -import { VueLoaderPlugin } from 'vue-loader' +const fs = require('fs') +const path = require('path') +const webpack = require('webpack') +const WebpackBar = require('webpackbar') +const { VueLoaderPlugin } = require('vue-loader') // const srcDir = path.join(__dirname, '..', 'src') -export default { - devtool: 'inline-source-map', - mode: 'development', - entry: fs.readdirSync(__dirname) - .reduce((entries, dir) => { - const fullDir = path.join(__dirname, dir) +module.exports = (isBrowser) => { + const extraAliases = {} + if (isBrowser) { + extraAliases['./ssr$'] = path.resolve(__dirname, '../build/stub.js') + } - if (dir === 'ssr') { - entries[dir] = path.join(fullDir, 'browser.js') - } else if (dir === 'vue-router') { - const possibleEntries = ['browser', 'app'] - for (const entryName of possibleEntries) { - const entry = path.join(fullDir, entryName + '.js') + return { + devtool: 'inline-source-map', + mode: 'development', + entry: fs.readdirSync(__dirname) + .reduce((entries, dir) => { + const fullDir = path.join(__dirname, dir) - if (fs.statSync(fullDir).isDirectory() && fs.existsSync(entry)) { - entries[dir] = entry - break + if (dir === 'ssr') { + entries[dir] = path.join(fullDir, 'browser.js') + } else if (dir === 'vue-router') { + const possibleEntries = ['browser', 'app'] + for (const entryName of possibleEntries) { + const entry = path.join(fullDir, entryName + '.js') + + if (fs.statSync(fullDir).isDirectory() && fs.existsSync(entry)) { + entries[dir] = entry + break + } } } - } - return entries - }, {}), - output: { - path: path.join(__dirname, '__build__'), - filename: '[name].js', - chunkFilename: '[id].chunk.js', - publicPath: '/__build__/' - }, - module: { - rules: [ - { - test: /\.tsx?$/, - use: 'ts-loader', - exclude: /node_modules/ - }, - { - test: /\.js$/, - exclude: /node_modules/, - use: 'babel-loader' - }, - { - test: /\.vue$/, - use: 'vue-loader' + return entries + }, {}), + output: { + path: path.join(__dirname, '__build__'), + filename: '[name].js', + chunkFilename: '[id].chunk.js', + publicPath: '/__build__/' + }, + module: { + rules: [ + { + test: /\.tsx?$/, + use: 'ts-loader', + exclude: /node_modules/ + }, + { + test: /\.vue$/, + use: 'vue-loader' + } + ] + }, + resolve: { + extensions: ['.tsx', 'd.ts', '.ts', '.js', '.vue'], + alias: { + // this isn't technically needed, since the default `vue` entry for bundlers + // is a simple `export * = require(''@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-bundler.js', + 'vue-meta': path.resolve(__dirname, '../src/'), + ...extraAliases } - ] - }, - resolve: { - extensions: ['.tsx', 'd.ts', '.ts', '.js', '.vue'], - alias: { - // 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-bundler.js', - 'vue-meta': path.resolve(__dirname, '../src/') + }, + // Expose __dirname to allow automatically setting basename. + context: __dirname, + node: { + __dirname: true + }, + plugins: [ + new WebpackBar(), + new VueLoaderPlugin(), + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'), + __DEV__: JSON.stringify(process.env.NODE_ENV !== 'production'), + __BROWSER__: JSON.stringify(true), + 'process.client': JSON.stringify(true), + 'process.server': JSON.stringify(false) + }) + ], + devServer: { + inline: true, + hot: true, + stats: 'minimal', + contentBase: __dirname, + overlay: true } - }, - // Expose __dirname to allow automatically setting basename. - context: __dirname, - node: { - __dirname: true - }, - plugins: [ - new WebpackBar(), - new VueLoaderPlugin(), - new webpack.DefinePlugin({ - 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'), - __DEV__: JSON.stringify(process.env.NODE_ENV !== 'production'), - __VUE_OPTIONS_API__: JSON.stringify(true), - __VUE_PROD_DEVTOOLS__: JSON.stringify(true) - }) - ], - devServer: { - inline: true, - hot: true, - stats: 'minimal', - contentBase: __dirname, - overlay: true } } diff --git a/jest.config.js b/jest.config.js index e11fe33..2e8cdb7 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,5 +1,6 @@ module.exports = { testEnvironment: 'jest-environment-jsdom-global', + preset: 'ts-jest', expand: true, @@ -41,6 +42,7 @@ module.exports = { ], globals: { - __DEV__: true + __DEV__: true, + __BROWSER__: true, } } diff --git a/package.json b/package.json index 56eddbb..09de855 100644 --- a/package.json +++ b/package.json @@ -2,13 +2,16 @@ "name": "vue-meta", "version": "2.3.3", "description": "Manage HTML metadata in Vue.js components with SSR support", - "main": "dist/vue-meta.common.js", - "web": "dist/vue-meta.js", - "module": "dist/vue-meta.esm.js", - "typings": "types/index.d.ts", + "main": "dist/vue-meta.cjs.js", + "unpkg": "dist/vue-meta.global.js", + "jsdelivr": "dist/vue-meta.global.js", + "module": "dist/vue-meta.esm-bundler.js", + "typings": "dist/vue-meta.d.ts", + "sideEffects": false, "files": [ - "dist", - "types/*.d.ts" + "dist/*.js", + "types/*.d.ts", + "README.md" ], "homepage": "https://github.com/nuxt/vue-meta", "bugs": "https://github.com/nuxt/vue-meta/issues", @@ -30,12 +33,12 @@ ], "author": "Pim (@pimlie)", "scripts": { - "build": "rimraf dist && rollup -c scripts/rollup.config.js", + "build": "yarn clean && rollup -c build/rollup.config.js", + "clean": "rimraf dist/*", "coverage": "codecov", - "dev": "babel-node examples/server.js", + "dev": "yarn clean && node examples/server.js", "docs": "vuepress dev --host 0.0.0.0 --port 3000 docs", "docs:build": "vuepress build docs", - "examples": "babel-node --extensions '.ts,.js' examples/server.js", "lint": "eslint --ext .js,.ts src test examples", "prerelease": "git checkout master && git pull -r", "release": "yarn lint && yarn test && standard-version", @@ -43,21 +46,25 @@ "test:e2e-ssr": "jest test/e2e/ssr", "test:e2e-browser": "jest test/e2e/browser", "test:unit": "jest test/unit", - "test:types": "tsc -p types/test" + "test:types": "tsc --build tsconfig.json" }, - "pperDependencies": { - "vue": "next" + "peerDependencies": { + "@vue/server-renderer": "^3.0.5", + "vue": "^3.0.0" }, "devDependencies": { "@babel/core": "^7.12.10", - "@babel/node": "^7.12.10", - "@babel/preset-env": "^7.12.11", + "@babel/plugin-transform-modules-commonjs": "^7.12.1", "@babel/preset-typescript": "^7.12.7", "@nuxtjs/eslint-config-typescript": "^5.0.0", + "@rollup/plugin-alias": "^3.1.1", + "@rollup/plugin-commonjs": "^17.0.0", + "@rollup/plugin-node-resolve": "^11.1.0", + "@rollup/plugin-replace": "^2.3.4", "@types/webpack": "^4.41.26", "@types/webpack-env": "^1.16.0", - "@typescript-eslint/eslint-plugin": "^4.13.0", - "@typescript-eslint/parser": "^4.13.0", + "@typescript-eslint/eslint-plugin": "^4.14.0", + "@typescript-eslint/parser": "^4.14.0", "@vue/compiler-sfc": "^3.0.5", "@vue/server-renderer": "^3.0.5", "@vue/server-test-utils": "^1.1.2", @@ -69,7 +76,7 @@ "babel-plugin-global-define": "^1.0.3", "babel-plugin-module-resolver": "^4.1.0", "browserstack-local": "^1.4.8", - "chromedriver": "^87.0.5", + "chromedriver": "^88.0.0", "codecov": "^3.8.1", "consola": "^2.15.0", "eslint": "^7.18.0", @@ -79,17 +86,13 @@ "jest": "^26.6.3", "jest-environment-jsdom": "^26.6.2", "jest-environment-jsdom-global": "^2.0.4", + "jiti": "^1.3.0", "jsdom": "^16.4.0", "lodash": "^4.17.20", "node-env-file": "^0.1.8", "puppeteer-core": "^5.5.0", "rimraf": "^3.0.2", - "rollup": "^2.36.2", - "rollup-plugin-babel": "^4.4.0", - "rollup-plugin-commonjs": "^10.1.0", - "rollup-plugin-json": "^4.0.0", - "rollup-plugin-node-resolve": "^5.2.0", - "rollup-plugin-replace": "^2.2.0", + "rollup": "^2.38.0", "rollup-plugin-terser": "^7.0.2", "rollup-plugin-typescript2": "^0.29.0", "selenium-webdriver": "^4.0.0-alpha.8", @@ -97,15 +100,14 @@ "tib": "^0.7.5", "ts-jest": "^26.4.4", "ts-loader": "^8.0.14", - "ts-node": "^9.1.1", "typescript": "^4.1.3", - "vue": "^3.0.0", + "vue": "^3.0.5", "vue-jest": "^3.0.7", "vue-loader": "^16.0.0", "vue-router": "next", - "webpack": "^5.15.0", - "webpack-bundle-analyzer": "^4.3.0", - "webpack-cli": "^4.3.1", + "webpack": "^5.17.0", + "webpack-bundle-analyzer": "^4.4.0", + "webpack-cli": "^4.4.0", "webpack-dev-server": "^3.11.2", "webpackbar": "^4.0.0" } diff --git a/scripts/rollup.config.js b/scripts/rollup.config.js deleted file mode 100644 index f0d9a72..0000000 --- a/scripts/rollup.config.js +++ /dev/null @@ -1,181 +0,0 @@ -import commonjs from 'rollup-plugin-commonjs' -import nodeResolve from 'rollup-plugin-node-resolve' -import json from 'rollup-plugin-json' -import babel from 'rollup-plugin-babel' -import replace from 'rollup-plugin-replace' -import { terser } from 'rollup-plugin-terser' -import defaultsDeep from 'lodash/defaultsDeep' -import { defaultOptions } from '../src/shared/constants' - -const pkg = require('../package.json') - -const version = pkg.version - -const banner = `/** - * vue-meta v${version} - * (c) ${new Date().getFullYear()} - * - Declan de Wet - * - Sébastien Chopin (@Atinux) - * - Pim (@pimlie) - * - All the amazing contributors - * @license MIT - */ -` - -const babelConfig = () => ({ - presets: [ - ['@babel/preset-env', { - /*useBuiltIns: 'usage', - corejs: 2,*/ - targets: { - node: 8, - ie: 9, - safari: '5.1' - } - }] - ] -}) - -const internalObjectProperties = [ - // Plugin options - // NOTE, see shared/options for why/how this is possible to do - ...Object.keys(defaultOptions), - 'refreshOnceOnNavigation', - // Runtime state props on $root._vueMeta - 'appId', - 'pausing', - 'navGuards', - 'initialized', - 'initializing', - 'deprecationWarningShown', - // updateClientMetaInfo return props - 'tagsAdded', - 'tagsRemoved', - // escapeOptions - 'doEscape', - // deepmerge - 'isMergeableObject', - 'arrayMerge' -] - -const terserOpts = { - nameCache: {}, - mangle: { - properties: { - //debug: '___DEBUGGGG___', - // minimize all object properties except when they are quotes like obj['prop'] - keep_quoted: "strict", - // and minimize props listed in internalObjectProperties - regex: new RegExp(`^(${internalObjectProperties.join('|')})$`) - } - } -} - -function rollupConfig({ - plugins = [], - ...config - }) { - - const isBrowserBuild = !config.output || !config.output.format || config.output.format === 'umd' || config.output.file.includes('.browser.') - - const replaceConfig = { - exclude: 'node_modules/(?!is-mergeable-object)', - delimiters: ['', ''], - values: { - // replaceConfig needs to have some values - 'const polyfill = process.env.NODE_ENV === \'test\'': 'const polyfill = true', - 'process.env.VERSION': `"${version}"`, - 'process.server' : isBrowserBuild ? 'false' : 'true', - /* remove unused stuff from deepmerge */ - // remove react stuff from is-mergeable-object - '|| isReactElement(value)': '|| false', - // we always provide an arrayMerge, remove default - '|| defaultArrayMerge' : '', - // clone is a deprecated option we dont use - 'options.clone ' : 'false ', - // we dont provide a custom merge - 'options.customMerge)' : 'false)', - // we dont use this helper - 'deepmerge.all = ' : 'false;', - // we dont use symbols on our objects - '.concat(getEnumerableOwnPropertySymbols(target))': '' - } - } - - /* / keep simple polyfills when babel plugin is used for build - if (plugins && plugins.some(p => p.name === 'babel')) { - replaceConfig.values = { - 'const polyfill = process.env.NODE_ENV === \'test\'': 'const polyfill = true', - } - }*/ - - return defaultsDeep({}, config, { - input: 'src/index.js', - output: { - name: 'VueMeta', - format: 'umd', - sourcemap: false, - banner - }, - plugins: [ - json(), - nodeResolve(), - replace(replaceConfig), - commonjs(), - babel(babelConfig()), - ].concat(plugins), - }) -} - -export default [ - // umd web build - { - output: { - file: pkg.web, - } - }, - // minimized umd web build - { - output: { - file: pkg.web.replace('.js', '.min.js'), - }, - plugins: [ - terser(terserOpts) - ] - }, - // common js build - { - output: { - file: pkg.main, - format: 'cjs' - }, - external: Object.keys(pkg.dependencies) - }, - // esm build - { - output: { - file: pkg.web.replace('.js', '.esm.js'), - format: 'es' - }, - external: Object.keys(pkg.dependencies) - }, - // browser esm build - { - output: { - file: pkg.web.replace('.js', '.esm.browser.js'), - format: 'es' - }, - external: Object.keys(pkg.dependencies) - }, - // minimized browser esm build - { - output: { - file: pkg.web.replace('.js', '.esm.browser.min.js'), - format: 'es' - }, - plugins: [ - terser(terserOpts) - ], - external: Object.keys(pkg.dependencies) - } -].map(rollupConfig) diff --git a/scripts/update-cdn.js b/scripts/update-cdn.js deleted file mode 100644 index 89e9a23..0000000 --- a/scripts/update-cdn.js +++ /dev/null @@ -1,36 +0,0 @@ -import { readFileSync, writeFileSync } from 'fs' -import updateSection from 'update-section' -import { name, main, version } from '../package.json' - -console.log(`Updating CDN info to latest v${version} release...`) - -const readmePath = './README.md' -const cdnUrl = `https://unpkg.com/${name}@${version}/${main}` -const minifiedUrl = cdnUrl.replace('.js', '.min.js') - -const content = readFileSync(readmePath, 'utf-8') - -const update = ` - - **Uncompressed:** - \`\`\`html - - \`\`\` - - **Minified:** - \`\`\`html - - \`\`\` - -`.trim().replace(/ {2}/gm, '') - -const updated = updateSection( - content, - update, - (line) => (/