Repository nuxt.js

Importing pages from another module

Zakini
0
Zakini
commented 9 months ago

I'm building an app with Nuxt and would like to separate out some of the pages into another folder. Effectively, I'd like to combine 2 or more sets of Nuxt files and combine them into a single app.

Here's the folder structure I'm trying:

app
└─ packages
   ├─ main
   │  ├─ assets
   │  ├─ components
   │  ├─ pages
   │  ├─ store
   │  ├─ (other nuxt folders...)
   │  └─ nuxt.config.js
   └─ plugin-a
      ├─ assets
      ├─ components
      ├─ (other nuxt folders...)
      ├─ index.js
      └─ nuxt.config.js

I'm using the express-template for the main package and the starter-template for the plugin-a package. The index.js in plugin-a creates and builds a Nuxt instance, then exports it. server/index.js in main will then import this Nuxt instance and set up an express route to render it.

Here's the code:

plugin-a/index.js

const { Nuxt, Builder } = require('nuxt')

const nuxtConfig = require('./nuxt.config')
nuxtConfig.dev = !(process.env.NODE_ENV === 'production')

// Init Nuxt.js
const nuxt = new Nuxt(nuxtConfig)

// Build only in dev mode
if (nuxtConfig.dev) {
  new Builder(nuxt).build()
}

module.exports = nuxt

main/server/index.js

import express from 'express'
import { Nuxt, Builder } from 'nuxt'
import pluginA from 'plugin-a'  // import the plugin nuxt instance

import api from './api'

const app = express()
const host = process.env.HOST || '127.0.0.1'
const port = process.env.PORT || 3000

app.set('port', port)

// Import API Routes
app.use('/api', api)

// Import and Set Nuxt.js options
let config = require('../nuxt.config.js')
config.dev = !(process.env.NODE_ENV === 'production')

// Init Nuxt.js
const nuxt = new Nuxt(config)

// Build only in dev mode
if (config.dev) {
  new Builder(nuxt).build()
}

// Give nuxt middleware to express
app.use('/main', nuxt.render)
app.use('/plugina', pluginA.render)  // render the plugin

// Listen the server
app.listen(port, host)
console.log('Server listening on ' + host + ':' + port) // eslint-disable-line no-console

The problem is Nuxt.render only seems to use the files in the current directory, so both /main and /plugina show the pages from the main package. Alternatively, if I try calling new Builder(pluginA).build() in main/server/index.js I get unexpected token errors in .nuxt/client.js (I assume Nuxt doesn't like Builder.build being called more than once).

I'm pretty stuck at this point and I don't see any way to approach this, aside from rolling my own Vue SSR implementation to handle this.

If anyone has any ideas about how to split up a Nuxt app like this that they could share, I'd very much appreciate it.

0
microcipcip
207
microcipcip
commented 9 months ago

I think that even if you manged to set this up the nuxt rebuild would be so slow that it would be pointless. I'd just use one Nuxt instance and adapt the project to it, otherwise indeed you need to roll your own

0
Zakini
0
Zakini
commented 9 months ago

I've also tried a script that will copy the files from the main package and plugin package into a staging folder. I ensure the staging folder has a structure that Nuxt can work with.

Here's the folder structure for this approach:

app
└─ packages
   ├─ main
   │  ├─ src
   │  │  ├─ assets
   │  │  ├─ components
   │  │  ├─ pages
   │  │  ├─ store
   │  │  └─ (other nuxt folders...)
   │  ├─ staging
   │  │  └─ (nuxt folders combined from main/src and plugin-a)
   │  ├─ nuxt.config.js
   │  └─ package.json
   └─ plugin-a
      ├─ assets
      ├─ components
      ├─ (other nuxt folders...)
      ├─ index.js
      ├─ nuxt.config.js
      └─ package.json

One issue with this is that once the files have been copied from plugin-a to main/staging, we then need to make sure main can load the dependencies of plugin-a. To do this, app is setup as a lerna project and I install the dependencies with lerna bootstrap --hoist which hoists common dependencies into the project root:

app
├─ node_modules (dependencies required by both main and plugin-a)
└─ packages
   ├─ main
   │  ├─ node_modules (dependencies only required by main)
   │  ├─ src
   │  ├─ staging
   │  ├─ nuxt.config.js
   │  └─ package.json
   └─ plugin-a
      ├─ node_modules (dependencies only required by plugin-a)
      ├─ index.js
      ├─ nuxt.config.js
      └─ package.json

plugin-a is added as a dependency of main. lerna will then hoist all of plugin-a's dependencies into the project root since both main and plugin-a depend on them now. Adjusting the webpack/backpack configs ensure they can be correctly resolved:

config.resolve.modules = [
  path.resolve(__dirname, '../../node_modules'),
  path.resolve(__dirname, 'node_modules')
]
config.resolveLoader.modules = [
  path.resolve(__dirname, '../../node_modules'),
  path.resolve(__dirname, 'node_modules')
]

However, when I do this I get this error:

ERROR  Failed to compile with 2 errors

These dependencies were not found:

* jsdom in /Users/me/repos/test/node_modules/nuxt/dist/nuxt.js
* node-pre-gyp in /Users/me/repos/test/node_modules/fsevents/fsevents.js

To install them, you can run: npm install --save jsdom node-pre-gyp

I'm not sure what's going wrong here, especially since jsdom is an optional dependency of Nuxt.

0
galvez
845
galvez
commented a month ago

@Zakini this would require a significant change in Nuxt core -- closing this for now. This is likely to be possible after the 2.0 release, where we'll be working towards a more decoupled core.

0
Informations
QuestionUnresolved
#c2191 - Created 9 months ago