#javascript #node.js #express #mean-stack #nestjs
#javascript #node.js #выразить #имеется в виду-стек #nestjs
Вопрос:
Я начал изучать MEAN stack, и когда я перешел на Express, я увидел, что в express Framework существует дополнительный уровень, который называется NestJS. В нем было все, что я хотел, и у него был синтаксис, подобный Angular, поэтому он был идеальным для меня.
Но каждый новый шаг — это кошмар, документация вообще бесполезна. Сейчас я борюсь с фреймворком, чтобы добиться возможности обслуживать изображения и не использовать API для такого рода вызовов.
Я перепробовал все, что нашел в Интернете, например:
main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as bodyParser from 'body-parser';
import * as express from 'express';
import { join } from 'path';
import { NestExpressApplication } from '@nestjs/platform-express';
declare const module: any;
async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule);
app.useStaticAssets(join(__dirname, '..', 'public'));
app.enableCors({
origin: true,
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS',
credentials: true,
});
//I tried this 2 options (https://docs.nestjs.com/techniques/mvc) (https://whatthecode.dev/serve-static-files-with-nest-js/)
app.use('/resources', express.static(process.cwd() '\resources'));
app.useStaticAssets(join(__dirname, '..', '\public'));
app.use(bodyParser.json({ limit: '50mb' }));
app.use(bodyParser.urlencoded({ limit: '50mb', extended: true }));
//console.log(process.cwd());
await app.listen(3000);
if (module.hot) {
module.hot.accept();
module.hot.dispose(() => app.close());
}
}
bootstrap();
Я попытался поместить это в app.module следующим образом (это сработало, но всегда ищет index.html не изображения):
import { AnimalsModule } from './animals/animals.module';
import { SpeciesModule } from './species/species.module';
import { AuthModule } from './auth/auth.module';
import { UsersModule } from './users/users.module';
import { BreedModule } from './breed/breed.module';
import { StateModule } from './state/state.module';
import { PhotoModule } from './photo/photo.module';
@Module({
imports: [
ServeStaticModule.forRoot({
rootPath: join(__dirname, '..', 'public'), // <-- path to the static files
}),
TypeOrmModule.forRoot({
type: 'mysql',
host: 'localhost',
port: 3306,
username: 'root',
password: '',
database: 'nest',
entities: [__dirname '/**/*.entity{.ts,.js}'],
synchronize: true,
}),
AnimalsModule,
SpeciesModule,
BreedModule,
StateModule,
AuthModule,
UsersModule,
PhotoModule,
],
})
//It seems that ignores this register and just uses the method signature options
@Module({
imports: [MulterModule.register({
dest: './resources/tmp',
limits: { fieldSize: 25 * 1024 * 1024 * 1024, fileSize: 25 * 1024 * 1024 * 1024 }
})],
controllers: [AppController],
providers: [AppService],
})
export class AppModule { }
Как, черт возьми, я могу обслуживать изображения или файлы и избегать маршрутизации api?
Спасибо всем.
Комментарии:
1. Учитывая такую конфигурацию (которая кажется приемлемой), не могли бы вы поделиться своей структурой каталогов статической папки
public
и простым GET, который вы пробовали для некоторого статического ресурса?2. Привет, у меня есть такая структура: project / resources / tmp /files project / public (просто попробуйте это имя, потому что его чаще можно увидеть в примерах) И мой запрос GET помещается в браузер localhost:3000/resources/a.jpg или общедоступную папку. Если вам нужны другие вещи, скажите это мне. Большое спасибо
3. Тем не менее, вы настраиваете свой корневой путь следующим образом:
rootPath: join(__dirname, '..', 'public')
?4. Попробуйте поместить ваше
a.jpg
в project / public и ПОЛУЧИТЬ его через localhost:3000/a.jpg5. Корневой путь: join(__dirname, ‘..’, ‘public’)? Находится во втором файле исходного вопроса, и я попробовал этот запрос, и он возвращает маршрут 404, не найденный firefox
Ответ №1:
Это то, что я сделал:
-
в app.module.ts
import { ServeStaticModule } from '@nestjs/serve-static/dist/serve-static.module'; import { join } from 'path'; @Module({ imports: [ ServeStaticModule.forRoot({ rootPath: join(__dirname, '..', 'public'), }), ], })
-
Затем я создал «общедоступный» каталог на том же уровне, что и «src», «dir» и т.д.
-
Файл доступен по адресу: https://my-url/file.jpg
Комментарии:
1. я сделал это, но у меня есть эта ошибка «ENOENT: нет такого файла или каталога», это показывает, что файл не найден в distpublicindex.html
2. Разрешение ошибки «такого файла нет» можно найти здесь: github.com/nestjs/nest-cli/issues/320 Дополнение CompilerOptions.assets сработало для меня.
Ответ №2:
Используйте useStaticAssets()
метод ( ServeStaticModule
предназначен для обслуживания статического контента, такого как SPA). Итак, в качестве минимального примера ваш main.ts
должен выглядеть следующим образом):
async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule);
app.useStaticAssets(join(__dirname, '..', 'public'));
await app.listen(3000);
}
В приведенном выше примере ваши ресурсы обслуживаются из корня вашего приложения (например http://localhost:3000/example.png
.
Вы также можете передать параметры методу в oder, чтобы настроить путь, по которому обслуживаются ресурсы:
app.useStaticAssets(join(__dirname, '..', 'public'), {
prefix: '/public/',
});
В этом примере ваш путь имеет префикс public
(например http://localhost:3000/public/example.png
)
Ответ №3:
Есть два способа обслуживать статический контент в NestJs
. Либо используйте 1
, ЛИБО 2
.
1. Использование ServeStaticModule
в app.module.ts
import { Module } from '@nestjs/common';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';
import { mainModule } from 'process'
@Module({
imports: [
ServeStaticModule.forRoot({
rootPath: join(__dirname, '..', 'public'),
}),
],
})
export class AppModule {}
2. Использование NestExpressApplication
в main.ts [Даже по умолчанию Nest Js использует только Express]
import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { join } from 'path';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(
AppModule,
);
app.useStaticAssets(join(__dirname, '..', 'public'));
await app.listen(3000);
}
bootstrap();
Ответ №4:
добавьте это в main.ts замените «uploads» именем вашего каталога app.use(‘/uploads’,express.static(join(process.cwd(), ‘uploads’)));
Комментарии:
1. Не могли бы вы, пожалуйста, отредактировать это и объяснить, почему? В таком случае это также помогло бы другим людям обнаружить эту проблему, поскольку, скорее всего, автор первоначального вопроса уже решил проблему через 10 месяцев 😉
2. У меня это работает только для получения статического содержимого. Я могу загружать элементы без этого, но я этого не вижу
Ответ №5:
У меня была такая же проблема. Я также очень долго боролся с этой проблемой. Например: у вас есть папка для загрузки изображений. В App.module вам нужно использовать его:
ServeStaticModule.forRoot({
rootPath: join(__dirname, '..', 'client'),
}),
localhost: 3000/picture.png
если я использую папку «без клиента», мое изображение будет
ServeStaticModule.forRoot({
rootPath: join(__dirname, '..'),
}),
localhost: 3000 /клиент /picture.png
Ответ №6:
Идея @pzabrocki приводит меня к следующему минимально рабочему репозиторию: https://gitlab.com/hadrien-toma/nest-static-files
Чтобы поиграть с этим:
git clone https://gitlab.com/hadrien-toma/nest-static-files
yarn install
yarn run start
Затем my-file.json
подается в http://localhost:3333/my-file.json
.
Ответ №7:
Отдельное модульное решение, затем импортируйте его в AppModule.
import { Module } from '@nestjs/common';
import { ServeStaticModule } from '@nestjs/serve-static';
import { resolve } from 'path';
@Module({
imports: [
ServeStaticModule.forRoot(
(() => {
const publicDir = resolve('./public/files/');
const servePath = '/files';
return {
rootPath: publicDir,
// serveRoot - if you want to see files on another controller,
// e.g.: http://localhost:8088/files/1.png
serveRoot: servePath,
exclude: ['/api*'],
};
})()
),
],
})
export class PublicModule {}
Ответ №8:
Основной метод document nest с использованием модуля заключается в следующем:
ServeStaticModule.forRoot({
rootPath: join(__dirname, '..', 'upload'), // path to the static files image
}),
Но если вы получаете ошибку при поиске index.html
, вы можете использовать этот метод, который я также использовал
main.ts
import * as express from 'express';
app.use(express.static(join(__dirname, '../upload')))
Ответ №9:
вы можете перейти в корневой каталог, если ваша папка загрузки находится в rootdir, затем укажите путь к папке в renderPath следующим образом.
ServeStaticModule.forRoot({
rootPath: join(__dirname, '../../'),
renderPath: '/uploads',
})
Ответ №10:
Вы также можете использовать статический модуль express в nest js.
// ...imports
import * as express from 'express';
import { join } from 'path';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// serve static assets from the client/dist folder, change this to the correct path for your project
app.use(express.static(join(process.cwd(), '../client/dist/')));
//... you config
await app.listen(process.env.PORT);
}
bootstrap();
Заслуга:https://whatthecode.dev/serve-static-files-with-nest-js