如何从下一个js中的节点模块外部的文件夹导入模块
How to import modules from a folder outside node modules in next js
我一直在努力从 three.js 导入示例模块,我在我的项目中使用了 next.js(服务器端反应框架)在快递中使用自定义服务器。我的 服务器代码 看起来像这样 -
const express = require('express');
const next = require('next');
const favicon = require('serve-favicon');
var path = require('path');
let fs = require('fs')
const dev = process.env.NODE_ENV !== 'production';
const nextApp = next({ dev });
nextApp.prepare()
.then(() => {
let server = express(), options = {}, PORT = 3000, app = express()
if (dev) {
// DEVELOPMENT ///
// DEVELOPMENT ///
}
else {
// PRODUCTION ///
options = {
...options
}
// PRODUCTION ///
}
server.use(favicon(path.join(__dirname, "/favicon.ico")))
server.get('/', (req, res) => {
const actualPage = '/';
nextApp.render(req, res, actualPage);
});
server.get('*', (req, res) => {
const actualPage = '/not-found';
nextApp.render(req, res, actualPage);
// return handle(req, res)
});
server.listen((PORT), (err) => {
if (err) throw err
console.log('>> Ready on ' + PORT)
})
})
.catch((ex) => {
console.error(ex.stack)
process.exit(1)
})
我基本上 运行 一个 npx create-next-app 并在我的 next.js 项目中配置了一个 custom express server 用于动态路由,如您在上面的代码中所见。
然后,我使用 three.js 在我的 App.js 文件中导入和渲染的主组件中创建了一个场景。我的 home.js 组件看起来像这样 -
import React, { useState, useEffect } from 'react'
import * as THREE from 'three'
import { TrackballControls } from 'three/examples/jsm/controls/TrackballControls'
import "../src/assets/sass/home.scss"
const X = () => {
let parent, renderer, scene, camera, TrackballControls
useEffect(() => {
// renderer
renderer = new THREE.WebGLRenderer()
renderer.setSize( window.innerWidth, window.innerHeight )
document.body.appendChild( renderer.domElement )
// scene
scene = new THREE.Scene()
// camera
camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 100 )
camera.position.set( 20, 20, 20 )
// controls
controls = new TrackballControls( camera )
controls.minDistance = 5
controls.maxDistance = 250
controls.enableDamping = true; // an animation loop is required when either damping or auto-rotation are enabled
controls.dampingFactor = 0.05;
// axes
// scene.add(new THREE.AxisHelper( 20 ))
// geometry
let geometry = new THREE.SphereGeometry( 2, 8, 6, 0, 6.3, 0, 3.1)
// material
let material = new THREE.MeshBasicMaterial({
wireframe: true,
wireframeLinewidth: 1
})
let sphere = new THREE.Mesh( geometry, material )
// parent
parent = new THREE.Object3D()
scene.add( parent )
scene.add( sphere )
function animate() {
requestAnimationFrame( animate )
parent.rotation.z += 0.01
controls.update()
renderer.render( scene, camera )
}
animate()
}
,[])
return <div></div>
}
export default X
现在这就是我面临的问题 - 我正在从 three.js 导入一个名为 TrackballControls 的示例模块,它不完全在核心三模块中,但是在它外面的文件夹中,您可以从路径中看到 - 'three/examples/jsm/controls/TrackballControls.js'。你可以在这里看到更多 - Importing es6 modules separately 。但不知何故,它不起作用。它会抛出
之类的错误
我尝试使用简单的 create-react-app 做同样的事情,导入完全有效!!所以我知道我的服务器端代码有问题,我假设这是一个与 webpack 相关的问题。但是我对 webpack 真的一无所知。有人请帮助我,我们将不胜感激!
这是我的 next.config.js 文件,如果有帮助的话 -
const withSASS = require('@zeit/next-sass')
const { parsed: localEnv } = require('dotenv').config()
const webpack = require('webpack')
// const path = require('path')
function HACK_removeMinimizeOptionFromCssLoaders(config) {
console.warn(
'HACK: Removing `minimize` option from `css-loader` entries in Webpack config',
)
config.module.rules.forEach(rule => {
if (Array.isArray(rule.use)) {
rule.use.forEach(u => {
if (u.loader === 'css-loader' && u.options) {
delete u.options.minimize
}
})
}
})
}
module.exports = withSASS(
{
webpack(config) {
HACK_removeMinimizeOptionFromCssLoaders(config)
config.plugins.push(new webpack.EnvironmentPlugin(localEnv))
return config
}
})
我知道这里没有人看到这个,但如果将来有人遇到这个问题,我会发布我的解决方案。所以这就是我想出来的 -
我在问题中没有提到我使用的是名为 next.js 的 SSR(服务器端渲染)反应框架。导入与纯 React 应用程序完美配合。但是在服务器端框架中,导入相关的东西应该在 useEffect(或 componentDidMount)中与其余的 threejs 东西一起完成。所以我像这样动态导入它 -
let dynamicallyImportPackage = async () => {
let TrackballControls
await import('three/examples/jsm/controls/TrackballControls')
// you can now use the package in here
.then(module => {
TrackballControls = module.TrackballControls
})
.catch(e => console.log(e))
return TrackballControls
}
然后,我像这样在我的useEffect中使用它-
let TrackbackControls = await dynamicallyImportPackage()
// controls
controls = new TrackbackControls(camera, container)
controls.minDistance = 5
controls.maxDistance = 250
Arigato Gosaimasu!
我一直在努力从 three.js 导入示例模块,我在我的项目中使用了 next.js(服务器端反应框架)在快递中使用自定义服务器。我的 服务器代码 看起来像这样 -
const express = require('express');
const next = require('next');
const favicon = require('serve-favicon');
var path = require('path');
let fs = require('fs')
const dev = process.env.NODE_ENV !== 'production';
const nextApp = next({ dev });
nextApp.prepare()
.then(() => {
let server = express(), options = {}, PORT = 3000, app = express()
if (dev) {
// DEVELOPMENT ///
// DEVELOPMENT ///
}
else {
// PRODUCTION ///
options = {
...options
}
// PRODUCTION ///
}
server.use(favicon(path.join(__dirname, "/favicon.ico")))
server.get('/', (req, res) => {
const actualPage = '/';
nextApp.render(req, res, actualPage);
});
server.get('*', (req, res) => {
const actualPage = '/not-found';
nextApp.render(req, res, actualPage);
// return handle(req, res)
});
server.listen((PORT), (err) => {
if (err) throw err
console.log('>> Ready on ' + PORT)
})
})
.catch((ex) => {
console.error(ex.stack)
process.exit(1)
})
我基本上 运行 一个 npx create-next-app 并在我的 next.js 项目中配置了一个 custom express server 用于动态路由,如您在上面的代码中所见。
然后,我使用 three.js 在我的 App.js 文件中导入和渲染的主组件中创建了一个场景。我的 home.js 组件看起来像这样 -
import React, { useState, useEffect } from 'react'
import * as THREE from 'three'
import { TrackballControls } from 'three/examples/jsm/controls/TrackballControls'
import "../src/assets/sass/home.scss"
const X = () => {
let parent, renderer, scene, camera, TrackballControls
useEffect(() => {
// renderer
renderer = new THREE.WebGLRenderer()
renderer.setSize( window.innerWidth, window.innerHeight )
document.body.appendChild( renderer.domElement )
// scene
scene = new THREE.Scene()
// camera
camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 100 )
camera.position.set( 20, 20, 20 )
// controls
controls = new TrackballControls( camera )
controls.minDistance = 5
controls.maxDistance = 250
controls.enableDamping = true; // an animation loop is required when either damping or auto-rotation are enabled
controls.dampingFactor = 0.05;
// axes
// scene.add(new THREE.AxisHelper( 20 ))
// geometry
let geometry = new THREE.SphereGeometry( 2, 8, 6, 0, 6.3, 0, 3.1)
// material
let material = new THREE.MeshBasicMaterial({
wireframe: true,
wireframeLinewidth: 1
})
let sphere = new THREE.Mesh( geometry, material )
// parent
parent = new THREE.Object3D()
scene.add( parent )
scene.add( sphere )
function animate() {
requestAnimationFrame( animate )
parent.rotation.z += 0.01
controls.update()
renderer.render( scene, camera )
}
animate()
}
,[])
return <div></div>
}
export default X
现在这就是我面临的问题 - 我正在从 three.js 导入一个名为 TrackballControls 的示例模块,它不完全在核心三模块中,但是在它外面的文件夹中,您可以从路径中看到 - 'three/examples/jsm/controls/TrackballControls.js'。你可以在这里看到更多 - Importing es6 modules separately 。但不知何故,它不起作用。它会抛出
之类的错误我尝试使用简单的 create-react-app 做同样的事情,导入完全有效!!所以我知道我的服务器端代码有问题,我假设这是一个与 webpack 相关的问题。但是我对 webpack 真的一无所知。有人请帮助我,我们将不胜感激!
这是我的 next.config.js 文件,如果有帮助的话 -
const withSASS = require('@zeit/next-sass')
const { parsed: localEnv } = require('dotenv').config()
const webpack = require('webpack')
// const path = require('path')
function HACK_removeMinimizeOptionFromCssLoaders(config) {
console.warn(
'HACK: Removing `minimize` option from `css-loader` entries in Webpack config',
)
config.module.rules.forEach(rule => {
if (Array.isArray(rule.use)) {
rule.use.forEach(u => {
if (u.loader === 'css-loader' && u.options) {
delete u.options.minimize
}
})
}
})
}
module.exports = withSASS(
{
webpack(config) {
HACK_removeMinimizeOptionFromCssLoaders(config)
config.plugins.push(new webpack.EnvironmentPlugin(localEnv))
return config
}
})
我知道这里没有人看到这个,但如果将来有人遇到这个问题,我会发布我的解决方案。所以这就是我想出来的 -
我在问题中没有提到我使用的是名为 next.js 的 SSR(服务器端渲染)反应框架。导入与纯 React 应用程序完美配合。但是在服务器端框架中,导入相关的东西应该在 useEffect(或 componentDidMount)中与其余的 threejs 东西一起完成。所以我像这样动态导入它 -
let dynamicallyImportPackage = async () => {
let TrackballControls
await import('three/examples/jsm/controls/TrackballControls')
// you can now use the package in here
.then(module => {
TrackballControls = module.TrackballControls
})
.catch(e => console.log(e))
return TrackballControls
}
然后,我像这样在我的useEffect中使用它-
let TrackbackControls = await dynamicallyImportPackage()
// controls
controls = new TrackbackControls(camera, container)
controls.minDistance = 5
controls.maxDistance = 250
Arigato Gosaimasu!