mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-21 21:25:11 +00:00
feat: nuxt bridge (#459)
This commit is contained in:
parent
de57626a7a
commit
44458fcbbb
14
.github/workflows/ci.yml
vendored
14
.github/workflows/ci.yml
vendored
@ -57,7 +57,7 @@ jobs:
|
||||
- name: Test (presets)
|
||||
run: yarn test:presets
|
||||
|
||||
test-compat:
|
||||
test-bridge:
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
@ -73,24 +73,24 @@ jobs:
|
||||
cache: 'yarn'
|
||||
cache-dependency-path: |
|
||||
yarn.lock
|
||||
test/fixtures/compat/yarn.lock
|
||||
test/fixtures/bridge/yarn.lock
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn --immutable
|
||||
|
||||
- name: Install dependencies (compat fixture)
|
||||
run: yarn --immutable && cd test/fixtures/compat && yarn --immutable
|
||||
- name: Install dependencies (bridge fixture)
|
||||
run: yarn --immutable && cd test/fixtures/bridge && yarn --immutable
|
||||
|
||||
- name: Stub
|
||||
run: yarn stub
|
||||
|
||||
- name: Test (presets compat)
|
||||
run: yarn test:compat
|
||||
- name: Test (presets bridge)
|
||||
run: yarn test:bridge
|
||||
|
||||
build-release:
|
||||
needs:
|
||||
- test
|
||||
- test-compat
|
||||
- test-bridge
|
||||
- lint
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
Getting started with Nuxt3 is straightforward.
|
||||
|
||||
💡 Do you want to experience and prepare your project for Nuxt 3 without breaking changes? Check out [Nuxt Bridge](/bridge/intro) page!
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before installing Nuxt, you'll need to have a local development environment.
|
||||
|
@ -9,8 +9,6 @@ Nuxt3 is powered by a new server engine, code-named Nitro. It has:
|
||||
- Hybrid mode for static + serverless sites
|
||||
- A development mode with hot module reloading
|
||||
|
||||
In addition it is backwards compatible with Nuxt2 via [a compatibility module](/server/compat).
|
||||
|
||||
## API Layer
|
||||
|
||||
Server [API endpoints](/server/api) and [Middleware](/server/middleware) are added by Nitro that internally uses [h3](https://github.com/unjs/h3).
|
||||
|
81
docs/content/7.bridge/1.intro.md
Normal file
81
docs/content/7.bridge/1.intro.md
Normal file
@ -0,0 +1,81 @@
|
||||
# Nuxt Bridge
|
||||
|
||||
> ⚠️ This section is work-in-progress and can change. Please check this page regularly.
|
||||
|
||||
Nuxt3 brings a brand-new experience for developing Vue applications.
|
||||
|
||||
To make this happen, we've rewritten most parts of nuxt codebase and are using the latest tooling such as Webpack5, vite, vue3 and native ESM.
|
||||
And we've also rethought how nuxt rendering works by introducing the `@nuxt/nitro` project.
|
||||
|
||||
Our goal is a smooth transition path from legacy stack to new one, reducing breaking changes as much as possible.
|
||||
|
||||
To make this happen, we considered backward- and forward-compatibility and most layers (such as modules and plugins). Nonetheless, this is in-progress and a bumpy road.
|
||||
|
||||
In the meantime, you can make sure your project is almost ready for nuxt3 and have latest DX experience, without major rewrites and risk of breaking changes by adding a simple module.
|
||||
|
||||
👉 Please see [Migration Guide](./migration) for more details how you can migrate your nuxt 2 project or module to bridge level.
|
||||
|
||||
## Nuxt 2 vs Nuxt Bridge vs Nuxt 3
|
||||
|
||||
In the table below, there is a quick comparation between 3 versions of nuxt:
|
||||
|
||||
Feature / Version | Nuxt 2 | Nuxt Bridge | Nuxt 3
|
||||
-----------------------|-----------------|------------------|---------
|
||||
Stability | 😸 Stable | 😺 Semi Stable | 🙀 Unstable
|
||||
Performance | 👎 Slower | 👍 Enhanced | 🔥 Fastest
|
||||
Nitro Engine | ❌ | ✅ | ✅
|
||||
ESM support | 🌙 Partial | 👍 Better | ✅
|
||||
Typescript | ☑️ Opt-in | 🚧 Faster | ✅
|
||||
Composition API | 📖 Community | 🚧 Nuxt3 API | ✅
|
||||
Components Auto Import | ✅ | ✅ | ✅
|
||||
Auto Imports | ❌ | 🚧 | ✅
|
||||
Webpack | 4 | 5 | 5
|
||||
Vite | ⚠️ Partial | 🚧 Partial | 🚧 Experimental
|
||||
Nuxi CLI | ❌ Old | ✅ | ✅
|
||||
|
||||
## Nuxt 3 vs Nuxt 2
|
||||
|
||||
The good news is that most features from Nitro Engine and the new CLI, like `api` routes, will be supported when you use `@nuxt/bridge`.
|
||||
|
||||
Some features have been dropped from nuxt2, some still need to be implemented for nuxt3 and some are new in nuxt3.
|
||||
Biggest changes with nuxt3 other than the ones covered by bridge, are `vue2` to `vue3`, webpack5 and Core rewrite with new templating engine.
|
||||
|
||||
At the moment, there is no Nuxt 2 to Nuxt 3 migration guide nor is recommanded to do it due to potentially more changes coming.
|
||||
We are working to provide a stable migration guide and tooling to make it as smooth as possible.
|
||||
|
||||
In table below there is an overall feature comparation table (might be incomplete or outdated):
|
||||
|
||||
|
||||
Feature / Version | Nuxt 2 | Nuxt 3 | Changes required
|
||||
--------------------------|---------|----------|------------------
|
||||
Vue Version | 2 | 3 | Yes
|
||||
`app.vue` | ❌ | ✅ | -
|
||||
Assets | ✅ | ✅ | No
|
||||
Components | ✅ | ✅ | No
|
||||
Layouts | ✅ | ✅ | Yes
|
||||
Error Pages | ✅ | 🚧 | Yes
|
||||
Pages | ✅ | ✅ | Yes
|
||||
Pages: Dynamic Params | ✅ | ✅ | Yes
|
||||
Pages: _.vue | ✅ | ✅ | No
|
||||
Plugins | ✅ | ✅ | Yes (compatible by default)
|
||||
Store | ✅ | 🚧 | Yes
|
||||
Transitions | ✅ | 🚧 | ?
|
||||
Suspense | ❌ | ✅ | -
|
||||
Options API: `asyncData` | ✅ | 🚧 | ?
|
||||
Options API: `fetch` | ✅ | 🚧 | ?
|
||||
|
||||
|
||||
### Nuxt Module Compatibility
|
||||
|
||||
- All Nuxt 2 modules should be forward compatible with Nuxt 3 as long as they migrate to bridge (see [migration](./migration)) or if they are already following guidelines
|
||||
- All (upcoming) modules made with `@nuxt/kit` should be backward compatible with nuxt2 projects (even without bridge) as long as they are not depending on a nuxt3/bridge-only feature
|
||||
|
||||
### Nuxt Plugin Compatibility
|
||||
|
||||
- Most nuxt2 plugins should be forward compatible with nuxt3 with a magical compat layer we inject
|
||||
- Nuxt3 plugins are **not** backward compatible with nuxt2
|
||||
|
||||
### Vue compatibility
|
||||
|
||||
For plugins and composition API and components, it needs exclusive vue2 or vue3 support from plugins.
|
||||
By using [vue-demi](https://github.com/vueuse/vue-demi) they should be compatible with both nuxt2 and nuxt3.
|
@ -1,31 +0,0 @@
|
||||
# Nitro
|
||||
|
||||
> It is possible to use the Nuxt3 rendering engine (Nitro) with Nuxt2 via a compatibility module.
|
||||
|
||||
1. Install `@nuxt/nitro` as a devDependency:
|
||||
|
||||
```bash
|
||||
yarn add --dev @nuxt/nitro
|
||||
```
|
||||
|
||||
1. Add `@nuxt/nitro/compat` to `buildModules` inside `nuxt.config`:
|
||||
|
||||
```ts [nuxt.config.js]
|
||||
export default {
|
||||
buildModules: [
|
||||
'@nuxt/nitro/compat'
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
1. If you have selected `target: 'static'` in your `nuxt.config`, update the `build` script in package.json to be `nuxt generate`:
|
||||
|
||||
```json [package.json]
|
||||
{
|
||||
"scripts": {
|
||||
"build": "nuxt generate"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Now, when you build your project, Nitro will generate an optimized server bundle for fast, next-generation edge rendering.
|
130
docs/content/7.bridge/2.migration.md
Normal file
130
docs/content/7.bridge/2.migration.md
Normal file
@ -0,0 +1,130 @@
|
||||
# Bridge Migration
|
||||
|
||||
> ⚠️ This section is work-in-progress and can change. Please regulary check this page.
|
||||
|
||||
## ... I have a nuxt2 project
|
||||
|
||||
Migration to nuxt-bridge, should be almost straight forward!
|
||||
|
||||
**Why migrate:**
|
||||
|
||||
- It is risk-free! You can roll back by just commenting out one line in config
|
||||
- Makes your project almost ready for nuxt3 migration
|
||||
- Enjoy new DX improvements without major rewrites for vue3
|
||||
- Use nitro engine for platform agnostic and optimized deployments
|
||||
- Help us stabilize nuxt3 and discover flows
|
||||
- Bridge is more stable than nuxt3 at the moment for migration
|
||||
|
||||
### **Step 1:** Ensure using latest version of nuxt
|
||||
|
||||
Remove package lock file (`package-lock.json` and `yarn.lock`) and update to latest version of nuxt2 ([releases](https://github.com/nuxt/nuxt.js/releases)) or use `nuxt-edge` for latest updates and fixes.
|
||||
|
||||
### **Step 2:** Install bridge module
|
||||
|
||||
Install `@nuxt/bridge` as a devDependency:
|
||||
|
||||
```bash
|
||||
# Using npm
|
||||
npm install -D @nuxt/bridge
|
||||
|
||||
# Using yarn
|
||||
yarn add --dev @nuxt/bridge
|
||||
```
|
||||
|
||||
Add `@nuxt/bridge` to `buildModules` inside `nuxt.config`:
|
||||
|
||||
```ts [nuxt.config.js]
|
||||
export default {
|
||||
buildModules: [
|
||||
'@nuxt/bridge'
|
||||
],
|
||||
bridge: {
|
||||
nitro: true,
|
||||
// vite: true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If you have a project with `target: 'static'`, update "build" script to use `nuxt generate`
|
||||
|
||||
```json [package.json]
|
||||
{
|
||||
"scripts": {
|
||||
"build": "nuxt generate"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### **Step 3:** Avoid CommonJS synax
|
||||
|
||||
See [Migrating from CommonJS](#step-2-avoid-commonjs-syntax) from module author section.
|
||||
We need same steps for `plugins`, `store`, `pages`, `serverMiddleware` and `nuxt.config.js`.
|
||||
|
||||
### **Step 4:** Ensure everything goes well
|
||||
|
||||
Try with both `nuxt dev`, `nuxt build` and `nuxt start` if everything goes as expected
|
||||
If there is an issue, please report it to us or to relavant module repository.
|
||||
|
||||
If you cannot take the risk of using experimental code, you can comment out the module and regularly check back to ensure your project stays ready for nuxt3 compatibily.
|
||||
|
||||
### 🥳 Enjoy new possibilities!
|
||||
|
||||
Everything goes well? Congratulations! You are welcome to enjoy new features from nuxt3 without full migration. See table in intro section for more.
|
||||
|
||||
## ... I am a module author
|
||||
|
||||
When users of nuxt3 use your module, a compatible module container layer from `@nuxt/kit` is automatically injected
|
||||
so as long as your code is following below guidelines, it should continue working as is.
|
||||
|
||||
### **Step 1:** Test it with `@nuxt/bridge`:
|
||||
|
||||
Migrating to `@nuxt/bridge` is the first and most important step for supporting nuxt3.
|
||||
|
||||
If you have a fixture in your module, add `@nuxt/bridge` package to its config (same steps as previous section for nuxt2 projects)
|
||||
|
||||
### **Step 2:** Avoid CommonJS syntax:
|
||||
|
||||
Nuxt natively supports Typescript and ECMAScript Modules. In every file make sure to:
|
||||
|
||||
- Change `require('lib')` to `import lib from 'lib'` or `await import('lib').then(e => e.default || e)`
|
||||
- Change `module.exports` to `export default` or `export const`
|
||||
- Avoid usage of `__dirname` and `__filename` as much as possible
|
||||
|
||||
### **Step 3:** Ensure plugins have default export
|
||||
|
||||
If you inject a nuxt plugin that does not have `export default` (such as global Vue plugins), ensure you add `export default {}` to the end of it
|
||||
|
||||
### **Step 4:** Avoid runtime modules
|
||||
|
||||
With nuxt3 and nitro project, we started to rethink how the nuxt build process should work and modules hooking into the Nuxt runtime is now considered an anti-pattern and will not work wtih nuxt3.
|
||||
|
||||
Your module should work fine by adding only to `buildModules[]` (instead of `modules[]`):
|
||||
|
||||
- Avoid updating `process.env` within nuxt module and reading by a nuxt plugin. Use `runtimeConfig` instead
|
||||
- (*) Avoid depending on runtime hooks like `vue-renderer:*` for production
|
||||
- (*) Avoid adding `serverMiddleware` by importing them inside module. Add them by referencing to file path so that they are independent of module context
|
||||
|
||||
(*) Unless it is for `nuxt dev` purpose only and guarded with `if (nuxt.options.dev) { }`.
|
||||
|
||||
### **Step 5**: Add module meta
|
||||
|
||||
Ensure your module is exporting meta object.
|
||||
|
||||
[TODO]
|
||||
|
||||
### **Step 6:** Migrate to typescript (optional)
|
||||
|
||||
While it is not essential, most of nuxt ecosystem is shifitng to use Typescript, it is highly recommended to consider migration.
|
||||
|
||||
**Tip:** You can start migration by simply renaming `.js` files, to `.ts`. Typescript is designed to be progressive!
|
||||
|
||||
**Tip:** You can use typescript syntax for nuxt 2/3 modules and plugins without any extra dependencies.
|
||||
|
||||
### 🛣️ Next Steps
|
||||
|
||||
While we are evolving nuxt3 and modules, you are welcome to share any ideas in Discussions section.
|
||||
|
||||
A brand new exprience of defining nuxt modules is coming with `@nuxt/kit` project but it is still not ready so it is advised only to try it and not release to stable versions of your module.
|
||||
|
||||
Please regularly check this section for latest updates.
|
||||
|
@ -19,7 +19,7 @@
|
||||
"lint": "eslint --ext .vue,.ts,.js .",
|
||||
"test": "yarn lint && yarn test:presets",
|
||||
"test:presets": "mocha test/presets/*.mjs",
|
||||
"test:compat": "TEST_COMPAT=1 yarn test:presets",
|
||||
"test:bridge": "TEST_BRIDGE=1 yarn test:presets",
|
||||
"test:unit": "mocha -r jiti/register packages/**/test/*.test.*",
|
||||
"version": "yarn && git add yarn.lock"
|
||||
},
|
||||
|
7
packages/bridge/build.config.ts
Normal file
7
packages/bridge/build.config.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { defineBuildConfig } from 'unbuild'
|
||||
|
||||
export default defineBuildConfig({
|
||||
entries: [
|
||||
'src/module'
|
||||
]
|
||||
})
|
32
packages/bridge/package.json
Normal file
32
packages/bridge/package.json
Normal file
@ -0,0 +1,32 @@
|
||||
{
|
||||
"name": "@nuxt/bridge",
|
||||
"version": "0.0.0",
|
||||
"repository": "nuxt/framework",
|
||||
"license": "MIT",
|
||||
"main": "./dist/module.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"prepack": "unbuild"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nuxt/kit": "^0.10.0",
|
||||
"@nuxt/nitro": "^0.10.0",
|
||||
"@nuxt/postcss8": "^1.1.3",
|
||||
"@vue/composition-api": "^1.1.3",
|
||||
"fs-extra": "^10.0.0",
|
||||
"node-fetch": "^2.6.1",
|
||||
"nuxi": "^0.10.0",
|
||||
"nuxt-swc": "^0.0.3",
|
||||
"nuxt-vite": "^0.2.1",
|
||||
"ufo": "^0.7.9",
|
||||
"upath": "^2.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/fs-extra": "^9.0.12",
|
||||
"@types/node-fetch": "^2.5.12",
|
||||
"unbuild": "^0.4.2"
|
||||
}
|
||||
}
|
39
packages/bridge/src/app.ts
Normal file
39
packages/bridge/src/app.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import { useNuxt, resolveModule } from '@nuxt/kit'
|
||||
import { resolve } from 'upath'
|
||||
import { distDir } from './dirs'
|
||||
|
||||
export function setupAppBridge () {
|
||||
const nuxt = useNuxt()
|
||||
|
||||
// Setup aliases
|
||||
nuxt.options.alias['#app'] = resolve(distDir, 'runtime/index.mjs')
|
||||
nuxt.options.alias['#build'] = nuxt.options.buildDir
|
||||
|
||||
// Resolve to same vue2 path
|
||||
nuxt.options.alias.vue = nuxt.options.alias.vue || resolveModule('vue/dist/vue.runtime.esm.js', { paths: nuxt.options.modulesDir })
|
||||
|
||||
// Transpile runtime/
|
||||
nuxt.options.build.transpile.push(resolve(distDir, 'runtime'))
|
||||
|
||||
// Add composition-api support
|
||||
// nuxt.options.alias['@vue/composition-api'] = require.resolve('@vue/composition-api/dist/vue-composition-api.mjs')
|
||||
// const capiPluginPath = resolve(distDir, 'runtime/capi.plugin.mjs')
|
||||
// addPluginTemplate({ filename: 'capi.plugin.mjs', src: capiPluginPath })
|
||||
// nuxt.hook('webpack:config', (configs) => {
|
||||
// // @ts-ignore
|
||||
// configs.forEach(config => config.entry.app.unshift(capiPluginPath))
|
||||
// })
|
||||
|
||||
// Fix wp4 esm
|
||||
nuxt.hook('webpack:config', (configs) => {
|
||||
for (const config of configs.filter(c => c.module)) {
|
||||
for (const rule of config.module.rules) {
|
||||
// @ts-ignore
|
||||
if (rule.test instanceof RegExp && rule.test.test('index.mjs')) {
|
||||
// @ts-ignore
|
||||
rule.type = 'javascript/auto'
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
import { Compiler } from 'webpack'
|
||||
import Template from 'webpack/lib/Template'
|
||||
|
||||
export default class AsyncLoadingPlugin {
|
||||
export class AsyncLoadingPlugin {
|
||||
apply (compiler: Compiler) {
|
||||
compiler.hooks.compilation.tap('AsyncLoading', (compilation) => {
|
||||
const mainTemplate = compilation.mainTemplate
|
4
packages/bridge/src/dirs.ts
Normal file
4
packages/bridge/src/dirs.ts
Normal file
@ -0,0 +1,4 @@
|
||||
import { resolve } from 'upath'
|
||||
|
||||
export const distDir = __dirname
|
||||
export const pkgDir = resolve(distDir, '..')
|
33
packages/bridge/src/module.ts
Normal file
33
packages/bridge/src/module.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import { defineNuxtModule, installModule } from '@nuxt/kit'
|
||||
import { setupNitroBridge } from './nitro'
|
||||
import { setupAppBridge } from './app'
|
||||
|
||||
export default defineNuxtModule({
|
||||
name: 'nuxt-bridge',
|
||||
configKey: 'bridge',
|
||||
defaults: {
|
||||
nitro: true,
|
||||
vite: false,
|
||||
app: true,
|
||||
// TODO: Remove from 2.16
|
||||
postcss8: true,
|
||||
swc: true
|
||||
},
|
||||
async setup (opts, nuxt) {
|
||||
if (opts.nitro) {
|
||||
await setupNitroBridge()
|
||||
}
|
||||
if (opts.app) {
|
||||
await setupAppBridge()
|
||||
}
|
||||
if (opts.vite) {
|
||||
await installModule(nuxt, require.resolve('nuxt-vite'))
|
||||
}
|
||||
if (opts.postcss8) {
|
||||
await installModule(nuxt, require.resolve('@nuxt/postcss8'))
|
||||
}
|
||||
if (opts.swc) {
|
||||
await installModule(nuxt, require.resolve('nuxt-swc'))
|
||||
}
|
||||
}
|
||||
})
|
@ -1,16 +1,14 @@
|
||||
import fetch from 'node-fetch'
|
||||
import { addPluginTemplate, useNuxt } from '@nuxt/kit'
|
||||
import { stringifyQuery } from 'ufo'
|
||||
import { resolve } from 'upath'
|
||||
import { move, readFile, writeFile } from 'fs-extra'
|
||||
import type { ModuleContainer } from '@nuxt/kit'
|
||||
import { build, generate, prepare } from './build'
|
||||
import { getNitroContext, NitroContext } from './context'
|
||||
import { createDevServer } from './server/dev'
|
||||
import { wpfs } from './utils/wpfs'
|
||||
import { resolveMiddleware } from './server/middleware'
|
||||
import AsyncLoadingPlugin from './webpack/wp4'
|
||||
import { readFile, writeFile } from 'fs-extra'
|
||||
import { build, generate, prepare, getNitroContext, NitroContext, createDevServer, wpfs, resolveMiddleware } from '@nuxt/nitro'
|
||||
import { AsyncLoadingPlugin } from './async-loading'
|
||||
import { distDir } from './dirs'
|
||||
|
||||
export default function nuxt2CompatModule (this: ModuleContainer) {
|
||||
const { nuxt } = this
|
||||
export function setupNitroBridge () {
|
||||
const nuxt = useNuxt()
|
||||
|
||||
// Ensure we're not just building with 'static' target
|
||||
if (!nuxt.options.dev && nuxt.options.target === 'static' && !nuxt.options._export && !nuxt.options._legacyGenerate) {
|
||||
@ -73,15 +71,15 @@ export default function nuxt2CompatModule (this: ModuleContainer) {
|
||||
})
|
||||
|
||||
// Nitro client plugin
|
||||
this.addPlugin({
|
||||
fileName: 'nitro.client.mjs',
|
||||
addPluginTemplate({
|
||||
filename: 'nitro.client.mjs',
|
||||
src: resolve(nitroContext._internal.runtimeDir, 'app/nitro.client.mjs')
|
||||
})
|
||||
|
||||
// Nitro server plugin (for vue-meta)
|
||||
this.addPlugin({
|
||||
fileName: 'nitro-compat.server.js',
|
||||
src: resolve(nitroContext._internal.runtimeDir, 'app/nitro-compat.server.js')
|
||||
addPluginTemplate({
|
||||
filename: 'nitro-bridge.server.mjs',
|
||||
src: resolve(distDir, 'runtime/nitro-bridge.server.mjs')
|
||||
})
|
||||
|
||||
// Fix module resolution
|
||||
@ -98,7 +96,7 @@ export default function nuxt2CompatModule (this: ModuleContainer) {
|
||||
nuxt.hook('build:compiled', async ({ name }) => {
|
||||
if (name === 'server') {
|
||||
const jsServerEntry = resolve(nuxt.options.buildDir, 'dist/server/server.js')
|
||||
await move(jsServerEntry, jsServerEntry.replace(/.js$/, '.cjs'))
|
||||
await writeFile(jsServerEntry.replace(/.js$/, '.cjs'), 'module.exports = require("./server.js")', 'utf8')
|
||||
await writeFile(jsServerEntry.replace(/.js$/, '.mjs'), 'export { default } from "./server.cjs"', 'utf8')
|
||||
} else if (name === 'client') {
|
||||
const manifest = await readFile(resolve(nuxt.options.buildDir, 'dist/server/client.manifest.json'), 'utf8')
|
||||
@ -185,7 +183,7 @@ function createNuxt2DevServer (nitroContext: NitroContext) {
|
||||
throw new Error('There is no server listener to call `server.renderRoute()`')
|
||||
}
|
||||
const html = await fetch(listener.url + route, {
|
||||
headers: { 'nuxt-render-context': encodeQuery(renderContext) }
|
||||
headers: { 'nuxt-render-context': stringifyQuery(renderContext) }
|
||||
}).then(r => r.text())
|
||||
|
||||
return { html }
|
||||
@ -200,9 +198,3 @@ function createNuxt2DevServer (nitroContext: NitroContext) {
|
||||
ready () { }
|
||||
}
|
||||
}
|
||||
|
||||
function encodeQuery (obj) {
|
||||
return Object.entries(obj).map(
|
||||
([key, val]) => `${encodeURIComponent(key)}=${encodeURIComponent(JSON.stringify(val))}`
|
||||
).join('&')
|
||||
}
|
6
packages/bridge/src/runtime/capi.plugin.mjs
Normal file
6
packages/bridge/src/runtime/capi.plugin.mjs
Normal file
@ -0,0 +1,6 @@
|
||||
import Vue from 'vue' // eslint-disable-line import/default
|
||||
import VueCompositionAPI from '@vue/composition-api'
|
||||
|
||||
Vue.use(VueCompositionAPI.default || VueCompositionAPI)
|
||||
|
||||
export default function () {}
|
10
packages/bridge/src/runtime/composables.mjs
Normal file
10
packages/bridge/src/runtime/composables.mjs
Normal file
@ -0,0 +1,10 @@
|
||||
const mock = () => () => { throw new Error('not implemented') }
|
||||
|
||||
export const useAsyncData = mock()
|
||||
export const asyncData = mock()
|
||||
export const defineNuxtComponent = mock()
|
||||
export const useSSRRef = mock()
|
||||
export const useData = mock()
|
||||
export const useGlobalData = mock()
|
||||
export const useHydration = mock()
|
||||
export const defineNuxtPlugin = mock()
|
1
packages/bridge/src/runtime/index.mjs
Normal file
1
packages/bridge/src/runtime/index.mjs
Normal file
@ -0,0 +1 @@
|
||||
export * from './composables'
|
@ -252,3 +252,10 @@ export function addVitePlugin (plugin: VitePlugin, options?: ExtendViteConfigOpt
|
||||
config.plugins.push(plugin)
|
||||
}, options)
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if current nuxt instance is version 2 legacy
|
||||
*/
|
||||
export function isNuxt2 (nuxt?: any) {
|
||||
return (nuxt || useNuxt()).version?.startsWith('v2')
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ export async function loadNuxt (opts: LoadNuxtOptions): Promise<Nuxt> {
|
||||
return nuxt
|
||||
}
|
||||
|
||||
// Compat
|
||||
// Nuxt 2
|
||||
// @ts-ignore
|
||||
const { loadNuxt } = tryRequireModule('nuxt-edge', resolveOpts) || requireModule('nuxt', resolveOpts)
|
||||
const nuxt = await loadNuxt({
|
||||
@ -76,7 +76,7 @@ export function buildNuxt (nuxt: Nuxt): Promise<any> {
|
||||
return build(nuxt)
|
||||
}
|
||||
|
||||
// Compat
|
||||
// Nuxt 2
|
||||
// @ts-ignore
|
||||
const { build } = tryRequireModule('nuxt-edge', resolveOpts) || requireModule('nuxt', resolveOpts)
|
||||
return build(nuxt)
|
||||
|
@ -4,7 +4,6 @@ export default defineBuildConfig({
|
||||
declaration: true,
|
||||
entries: [
|
||||
'src/index',
|
||||
'src/compat',
|
||||
{ input: 'src/runtime/', outDir: 'dist/runtime', format: 'esm' },
|
||||
{ input: 'src/runtime/', outDir: 'dist/runtime', format: 'cjs', declaration: false }
|
||||
],
|
||||
|
@ -1 +1,3 @@
|
||||
module.exports = require('./dist/compat')
|
||||
export default function () {
|
||||
throw new Error('Nitro compat for nuxt2 moved to nuxt bridge. Please check documentation for more details.')
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ export function dynamicRequire ({ dir, ignore, inline }: Options): Plugin {
|
||||
src: resolve(dir, id).replace(/\\/g, '/'),
|
||||
name: '_' + id.replace(/[^a-zA-Z0-9_]/g, '_'),
|
||||
meta: getWebpackChunkMeta(resolve(dir, id))
|
||||
}))
|
||||
})).filter(chunk => chunk.meta)
|
||||
|
||||
return inline ? TMPL_INLINE({ chunks }) : TMPL_LAZY({ chunks })
|
||||
}
|
||||
@ -75,10 +75,13 @@ export function dynamicRequire ({ dir, ignore, inline }: Options): Plugin {
|
||||
function getWebpackChunkMeta (src: string) {
|
||||
const chunk = require(src) || {}
|
||||
const { id, ids, modules } = chunk
|
||||
if (!id && !ids) {
|
||||
return null // Not a webpack chunk
|
||||
}
|
||||
return {
|
||||
id,
|
||||
ids,
|
||||
moduleIds: Object.keys(modules)
|
||||
moduleIds: Object.keys(modules || {})
|
||||
}
|
||||
}
|
||||
|
||||
|
2
test/fixtures/basic/package.json
vendored
2
test/fixtures/basic/package.json
vendored
@ -1,6 +1,6 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "fixture-compat",
|
||||
"name": "fixture-bridge",
|
||||
"scripts": {
|
||||
"build": "nuxt build"
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ global.__NUXT_PREPATHS__ = (global.__NUXT_PREPATHS__ || []).concat(__dirname)
|
||||
|
||||
export default defineNuxtConfig({
|
||||
buildModules: [
|
||||
'@nuxt/nitro/compat'
|
||||
'@nuxt/bridge'
|
||||
],
|
||||
serverMiddleware: [
|
||||
{
|
3
test/fixtures/bridge/pages/index.vue
vendored
Normal file
3
test/fixtures/bridge/pages/index.vue
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div>Hello Vue!</div>
|
||||
</template>
|
3
test/fixtures/compat/pages/index.vue
vendored
3
test/fixtures/compat/pages/index.vue
vendored
@ -1,3 +0,0 @@
|
||||
<template>
|
||||
<div>Hello Vue</div>
|
||||
</template>
|
@ -7,14 +7,14 @@ import execa from 'execa'
|
||||
import { expect } from 'chai'
|
||||
import { fixtureDir, resolveWorkspace } from '../utils.mjs'
|
||||
|
||||
const isCompat = Boolean(process.env.TEST_COMPAT)
|
||||
const isBridge = Boolean(process.env.TEST_BRIDGE)
|
||||
|
||||
export function importModule (path) {
|
||||
return import(pathToFileURL(path).href)
|
||||
}
|
||||
|
||||
export function setupTest (preset) {
|
||||
const fixture = isCompat ? 'compat' : 'basic'
|
||||
const fixture = isBridge ? 'bridge' : 'basic'
|
||||
const rootDir = fixtureDir(fixture)
|
||||
const buildDir = resolve(rootDir, '.nuxt-' + preset)
|
||||
|
||||
@ -25,7 +25,7 @@ export function setupTest (preset) {
|
||||
}
|
||||
|
||||
it('nitro build', async () => {
|
||||
const nuxtCLI = isCompat
|
||||
const nuxtCLI = isBridge
|
||||
? resolve(ctx.rootDir, 'node_modules/nuxt/bin/nuxt.js')
|
||||
: resolveWorkspace('packages/nuxi/bin/nuxi.js')
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user