nestjs / serve-static Goto Github PK
View Code? Open in Web Editor NEWServe static websites (SPA's) using Nest framework (node.js) π₯¦
Home Page: https://nestjs.com/
License: MIT License
Serve static websites (SPA's) using Nest framework (node.js) π₯¦
Home Page: https://nestjs.com/
License: MIT License
[ ] Regression
[ ] Bug report
[ x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
The forRoot module only allows for a single top-level directory.
It would be able to specify multiple paths. This would allow multiple, static sites to be hosted by the same Nest applications.
Serve more than one static site using the same instance of Nest/Serve-static
I have a pre-configured module I built ...
import { Module } from '@nestjs/common';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from "node:path";
@Module({
imports: [
ServeStaticModule.forRoot({
rootPath: join(process.cwd(), '..', 'client', 'dist')
})
],
exports: [
ServeStaticModule
]
})
export class ClientStaticModule { }
Tests all pass...
import { INestApplication } from '@nestjs/common';
import { HttpAdapterHost } from '@nestjs/core';
import { Test } from '@nestjs/testing';
import { ServeStaticModule } from './client.module';
describe('ClientModule', () => {
let app: INestApplication;
it('should be defined', async () => {
const moduleRef = await Test.createTestingModule({
imports: [ServeStaticModule.registerAsync()]
}).compile();
app = moduleRef.createNestApplication();
await app.init();
expect(moduleRef.get(HttpAdapterHost)).toBeInstanceOf(HttpAdapterHost);
});
afterAll(async () => {
await app.close();
})
});
But when importing this into my other project it throws an error.
Error
[Nest] 6704 - 11/17/2023, 8:49:58 PM ERROR [ExceptionHandler] Nest can't resolve dependencies of the ServeStaticModule (SERVE_STATIC_MODULE_OPTIONS, AbstractLoader, ?). Please make sure that the argument HttpAdapterHost at index [2] is available in the ServeStaticModule context.
Potential solutions:
- Is ServeStaticModule a valid NestJS module?
- If HttpAdapterHost is a provider, is it part of the current ServeStaticModule?
- If HttpAdapterHost is exported from a separate @Module, is that module imported within ServeStaticModule?
@Module({
imports: [ /* the Module containing HttpAdapterHost */ ]
})
Error: Nest can't resolve dependencies of the ServeStaticModule (SERVE_STATIC_MODULE_OPTIONS, AbstractLoader, ?). Please make sure that the argument HttpAdapterHost at index [2] is available in the ServeStaticModule context.
Potential solutions:
- Is ServeStaticModule a valid NestJS module?
- If HttpAdapterHost is a provider, is it part of the current ServeStaticModule?
- If HttpAdapterHost is exported from a separate @Module, is that module imported within ServeStaticModule?
@Module({
imports: [ /* the Module containing HttpAdapterHost */ ]
})
at Injector.lookupComponentInParentModules (/workspace/.yarn/unplugged/@nestjs-core-virtual-38511f33b2/node_modules/@nestjs/core/injector/injector.js:254:19)
at Injector.resolveComponentInstance (/workspace/.yarn/unplugged/@nestjs-core-virtual-38511f33b2/node_modules/@nestjs/core/injector/injector.js:207:33)
at resolveParam (/workspace/.yarn/unplugged/@nestjs-core-virtual-38511f33b2/node_modules/@nestjs/core/injector/injector.js:128:38)
at async Promise.all (index 2)
at Injector.resolveConstructorParams (/workspace/.yarn/unplugged/@nestjs-core-virtual-38511f33b2/node_modules/@nestjs/core/injector/injector.js:143:27)
at Injector.loadInstance (/workspace/.yarn/unplugged/@nestjs-core-virtual-38511f33b2/node_modules/@nestjs/core/injector/injector.js:70:13)
at Injector.loadProvider (/workspace/.yarn/unplugged/@nestjs-core-virtual-38511f33b2/node_modules/@nestjs/core/injector/injector.js:97:9)
at /workspace/.yarn/unplugged/@nestjs-core-virtual-38511f33b2/node_modules/@nestjs/core/injector/instance-loader.js:56:13
at async Promise.all (index 0)
at InstanceLoader.createInstancesOfProviders (/workspace/.yarn/unplugged/@nestjs-core-virtual-38511f33b2/node_modules/@nestjs/core/injector/instance-loader.js:55:9)
I've seen this on StackOverflow too... and I've checked the @nest/core
and @nest/common
versions and they are all the same...
I even set my yarn "resolutions" to ensure the correct verion
"resolutions": {
"@nestjs/common": "10.2.9",
"@nestjs/core": "10.2.9",
"@nestjs/platform-express": "10.2.9"
}
I cant link to an enterprise applicaiton
No response
The import to work when run
10.2.9
10.2.1
20.9.0
No response
[ ] Regression
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
ServeStaticModule.forRoot({
rootPath: join(__dirname, '..', '.well-known/apple-app-site-association'),
serveStaticOptions: { index: ['index.json'] },
}),
The code above does still not work if index.html is not available.
I want to serve the JSON file instead of HTML.
I need apple app site association file for the deep-linking iOS app with my backend.
Nest version: 6.11.11
For Tooling issues:
- Node version: 10.12.18
- Platform: Linux
Using the '@nestjs/serve-static' package and serving my static html file with it. After I set up the global prefix to my application, I can not reach my served root as I expected.
I couldn't find any documention/post about this issue.
As we can see from the images:
Tested with Fastify and Express as well, doesn't seem to work with either of them.
https://github.com/Bidghur/static-serve-issue
When I hit http://localhost:3000/globalprefix/static/example I should receive my static assets.
So the globalprefix should be added to my serve root path url.
@nestjs/common
@nestjs/core
@nestjs/microservices
@nestjs/platform-express
@nestjs/platform-fastify
@nestjs/platform-socket.io
@nestjs/platform-ws
@nestjs/testing
@nestjs/websockets
@nestjs/serve-static
9.4.3
"@nestjs/common": "^9.0.0",
"@nestjs/core": "^9.0.0",
"@nestjs/platform-express": "^9.0.0",
"@nestjs/serve-static": "^4.0.0",
"reflect-metadata": "^0.1.13",
"rxjs": "^7.2.0"
},
"devDependencies": {
"@nestjs/cli": "^9.0.0",
"@nestjs/schematics": "^9.0.0",
"@nestjs/testing": "^9.0.0",
"@types/express": "^4.17.13",
"@types/jest": "29.5.0",
"@types/node": "18.15.11",
"@types/supertest": "^2.0.11",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0",
"eslint": "^8.0.1",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"jest": "29.5.0",
"prettier": "^2.3.2",
"source-map-support": "^0.5.20",
"supertest": "^6.1.3",
"ts-jest": "29.0.5",
"ts-loader": "^9.2.3",
"ts-node": "^10.0.0",
"tsconfig-paths": "4.2.0",
"typescript": "^4.7.4"
}
18.9.0
No response
[ ] Regression
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
ServeStaticModule.forRoot({
rootPath: frontendPath,
exclude: ['', '/', '/events'],
}),
This config still serves my files on the base path of my application, even though i excluded it. It works correctly when calling /events
.
I'd expect no static serving when requesting http://localhost:4200/
I'm using angular to render the other routes.
@Module({
imports: [
AngularUniversalModule.forRoot({
bootstrap: AppServerModule,
viewsPath: frontendPath,
renderPath: '*',
}),
ServeStaticModule.forRoot({
rootPath: frontendPath,
exclude: ['', '/', '/events'],
}),
],
controllers: [AppController],
providers: [AppService],
})
I'd like my angular app to handle the root route
[ ] Regression
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
I have an API that serves basic endpoints (get/post). I want to add an endpoint which serve a directory which contains files.
NestJS return an error 500 because I don't have an index.html file in the folder ...
Add an option to disable the default routing on the index.html file and therefore be able to list the contents of a folder.
Build a basic API with get/post endpoints and also serve a directory on a custom path (for example: files uploaded or generated by the API).
Nest version: 7.0.0
@nestjs/serve-static version: 2.1.3
Webpack hot reloading works, serve static works. I can't see any way to have them work together. That is to say - serve static with hot reloading.
I would like to be able to use serve-static but with webpack hot reloading
Nest version: X.Y.Z
For Tooling issues:
- Node version: XX
- Platform:
Others:
[ ] Regression
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
A globally registered guard isn't called before content is served by this module.
Since global guards are supposed to apply to every endpoint, I'd expect them to also apply to content served by this module (at least as long as the global guard was registered by a module before the ServeStaticModule was registered), or at least for the module to have a configuration option to allow this.
ServeStatic
module, and configure it to serve some static files.I'm using Nest to write internal tooling which will be publicly accessible. I want to make sure no information is possibly leaked, so users will have to authenticate using our company-internal SSO. To implement this I created a strategy and guard and added them to the application using passport
. Since the guard isn't applied to content served by this module I have two choices:
Right now I'm leaning more towards the latter option, but this would mean circumventing Nest's application structure, which I'd like to avoid if possible.
Nest version: 7.2.0
Hello, I've taken your example https://github.com/nestjs/nest/tree/master/sample/24-serve-static, and added webpack builder in order to bundle everything in one file.
When build with 'production' mode set in webpack - there is an exception in runtime:
24-serve-static>npm run start:prod
> [email protected] start:prod \24-serve-static
> node dist/main
[Nest] 1736 - 02/20/2020, 2:20:43 PM [NestFactory] Starting Nest application...
(node:1736) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.
[Nest] 1736 - 02/20/2020, 2:20:43 PM [l] l dependencies initialized +14ms
(node:1736) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'getInstance' of undefined
but, if mode in webpack is commented - everything works fine.
In node_modules@nestjs\serve-static\dist\serve-static.module.js
let ServeStaticModule = ServeStaticModule_1 = class ServeStaticModule {
constructor(ngOptions, loader, httpAdapterHost) {
this.ngOptions = ngOptions;
this.loader = loader;
this.httpAdapterHost = httpAdapterHost;
httpAdapterHost in runtime is
{
httpAdapterHost: {
ioAdapter: null,
globalPrefix: '',
globalPipes: [],
globalFilters: [],
globalInterceptors: [],
globalGuards: [],
globalRequestPipes: [],
globalRequestFilters: [],
globalRequestInterceptors: [],
globalRequestGuards: []
}
see code here.
https://github.com/Serg-Mois/serve_static_webpack_bug
also, when build with webpack - you need explicitly add "fastify-static" into dependencies.
In some cases there is subfolders that is created dynamic. An example is a control for app based on a number.
Using path routers to represent the path
ServeStaticModule.forRoot({
rootPath: join(__dirname, '..', 'content', 'app', ':app_ID', 'assets'),
serveRoot: '/content/assets/:app_ID'
}),
app_ID here represents the dynamic route. Give the user the choice to better represent files in some context, like control user or app files
[ ] Regression
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
All the options other than setHeaders
and redirect
will not be effective if you are using Fastify as the adapter. The bug happens here https://github.com/nestjs/serve-static/blob/master/lib/loaders/fastify.loader.ts#L29 , fastify-static
doesn't have an option called send
(https://github.com/fastify/fastify-static/blob/master/index.js#L23).
Nest version: 7.0.8
Others:
I have a question regarding the purpose of this module:
Can I use this module to serve static assets like images, videos and other miscellaneous files?
With the provided example every request maps to an index.html
file inside the rootPath
and I wasn't able to figure out a way to access any other file within the rootPath
.
Am I missing something?
no
the idea is to have different versions for different JS files. There should be a default "latest" version for all clients not specifying a version, and versioning should be dealt with in a simple manner, like in a regular file system three. Also the number of folders and names should not be known in advance, and can be changed. example of folder structure:
and then clients would be able to fetch:
localhost/assets/js/some_js_asset --> latest
localhost/assets/js/some_js_asset/latest --> latest
localhost/assets/js/some_js_asset/3.0/ --> v3.0
localhost/assets/js/some_js_asset?version=3 --> v3.0
localhost/assets/js/some_js_asset?minVersion=2&maxVersion=3 --> v3.0
localhost/assets/js/some_other_unversioned_js_asset/ --> latest
etc ....
No response
the motivation is to have a server to serve microfrontend bundles for run-time mounting. see also: https://www.youtube.com/watch?v=QHunH3MFPZs&list=PLLUD8RtHvsAOhtHnyGx57EYXoaNsxGrTU&index=5
the rootPath directory will be mounted from a dynamic volume where CI pipelines would upload the compiled JS asset without having to restart the server
[ ] Regression
[ ] Bug report
[ x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
The ServeStaticModule
serves index.html
in various situations
/context-path
- will redirect using 301 and serve idnex from /contex-path/
/context-path/
- will serve index.html using express.static(clientPath, options.serveStaticOptions)
so we can use setHeaders
method to apply custom headers/context-path/some/path/that/falls/back/to/index
- will serve index.html using app.get(renderPath, renderFn);
and more preciselly res.sendFile(indexFilePath);
to which the serveStaticOptions
are NOT appliedIt would be great to be able to apply headers such as "Content-Security-Policy" on index.html undrr ALL circumstances, what would be the best way to acheive it ?
ServeStaticModule.forRoot({
rootPath: join(process.cwd(), 'public'),
serveRoot: '/context-path'
serveStaticOptions: {
maxAge: MAX_AGE_7_DAYS,
etag: false,
setHeaders: (res, path) => { // this covers 1. and 2. situation but NOT the 3. one
if (path.endsWith('index.html')) {
res.setHeader('Cache-Control', 'no-cache');
}
}
}
})
Being able to set same headers on index.html
under all circumstances.
Nest version: 6.14.2
For Tooling issues:
- Node version: v12.13.1
- Platform: Windows
Others:
the route set on serveRoot will return 404
https://github.com/ianzone/lambda-nestify/tree/serve-static
return the static site
3.0.1
9.3.9
v18.12.0
No response
[ ] Regression
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
loadPackage
is used from file lib/utils/service-static.utils.ts
loadPackage
should be used from @nestjs/common
"@nestjs/serve-static": "1.0.1"
For Tooling issues:
- Node version: XX
- Platform:
Others:
[ ] Regression
[x ] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
/project-root/node_modules/find-my-way/index.js:356
if (path.charCodeAt(0) !== 47) { // 47 is '/'
^
TypeError: path.charCodeAt is not a function
@Module({
imports: [
ServeStaticModule.forRoot({
renderPath:
/^\/(js|css|fonts|icons|locales|index\.html\??)\/?.+$|\/(robots\.txt|favicon\.ico)$/,
rootPath: join(APP_ROOT_PATH, 'public'),
}),
...
controllers: [AppControllers],
})
export class AppModule {}
## Environment
<pre><code>
Nest version: 8.0.0
For Tooling issues:
- Node version: v14.17.3
- Platform: Linux
Others: @nestjs/platform-fastify
</code></pre>
[ ] Regression
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
Not implemented
Same behavior than TypeOrmModule.forRootAsync(...)
[ ] Regression
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
Currently if you serveStatic alongside api routes, it would be nice if you could tell serve-static to ignore paths beginning with /api
via some options. This would allow /api/not-found
to return 404 from API, and not try and serve an index.html file. If there is some current way to do it, I'm also curious how I might get around this with middleware if necessary.
The /api
routes do not serve static on 404s.
Run a boilerplate nestjs app with serveStatic. add app.setGlobalPrefix('api')
and then try and hit /api/not-found-route-goes-here
and it will serve the index.html
.
monorepo api + webapp
Nest version: 6.12.9
For Tooling issues:
- Node version: v12.13.0
- Platform: Mac
Others:
N/A
[ ] Regression
[ ] Bug report
[x ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
We're using this plugin to serve up the client-side app and seeing console warnings (edit: these are only warnings) because .css files served do not have the correct mime-type. I don't see an ability in the options to map file extensions to mime types in order to solve this.
.css
file should be served with a mime-type of text/css
. I believe we should be able to map these mime types according to extension.
Send the correct mime-types in the headers for serving static files
Nest version: 7.4.2
For Tooling issues:
- Node version: v12.18.3
- Platform: Mac
Others:
In code, there is function setHeaders?: (res: any, path: string, stat: any) => any;
What is first, second and third any
?
I would like to set custom headers.
Describe in documentation
ServeStaticModule not work if any controller in module has @get('*')
[ ] Regression
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
Returns html content from @get('*') controller
Should return asset
@Module(
{
imports: [
ServeStaticModule.forRoot(
{
serveRoot: '/public',
renderPath: '/public',
rootPath: path.resolve(__dirname, 'public/'),
serveStaticOptions: {
index: false,
},
},
),
],
controllers: [
FrontController,
],
providers: [],
},
)
class FrontModule {}
@Controller()
export class FrontController {
@Get('*')
@Accepts('html')
index(@Res() res: Response) {
res.send('dupa2');
}
}
"@nestjs/common": "^7.5.5",
"@nestjs/core": "^7.5.5",
"@nestjs/platform-express": "^7.5.5",
"@nestjs/serve-static": "^2.1.4",
https://expressjs.com/en/4x/api.html#fallthrough
The ServeStaticOptions
type when using this Plugin is missing the fallthrough
property, which exists onNestExpressApplication#useStaticAssets
This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.
These updates have all been created already. Click a checkbox below to force a retry/rebase of any.
These are blocked by an existing closed PR and will not be recreated unless you click a checkbox below.
.circleci/config.yml
cimg/node 20.11
package.json
path-to-regexp 0.2.5
@commitlint/cli 19.1.0
@commitlint/config-angular 19.1.0
@nestjs/common 10.3.3
@nestjs/core 10.3.3
@types/node 20.11.27
@typescript-eslint/eslint-plugin 7.2.0
@typescript-eslint/parser 7.2.0
eslint 8.57.0
eslint-config-prettier 9.1.0
eslint-plugin-import 2.29.1
express 4.18.3
fastify 4.26.2
@fastify/static 6.12.0
husky 9.0.11
lint-staged 15.2.2
prettier 3.2.5
reflect-metadata 0.2.1
release-it 17.1.1
rxjs 7.8.1
typescript 5.4.2
@nestjs/common ^9.0.0 || ^10.0.0
@nestjs/core ^9.0.0 || ^10.0.0
express ^4.18.1
fastify ^4.7.0
@fastify/static ^6.5.0
I have a SvelteKit app where I've set precompress: true
to generate .br
files. I'd like to serve them from my Nest app.
https://kit.svelte.dev/docs/adapter-static#options-precompress
Support https://github.com/fastify/fastify-static?tab=readme-ov-file#precompressed
I thought from a quick glance at the source code that there was a chance the option would be passed straight through, but it didn't work in my testing.
Add it to the types and docs. It's not there now.
Greatly improves page load time by serving brotli and gzip compressed files
I am migrating my nestjs
project from v8
to v9
. The fastify-static
dependency in the latest version of nestjs@9
has been deprecated, and I have installed @fastify/static
. The project throws the following error:
[Nest] 72982 - 2022/07/08 δΈε5:36:44 ERROR [PackageLoader] The "fastify-static" package is missing. Please, make sure to install this library ($ npm install fastify-static) to take advantage of ServeStaticModule.
I checked the source code of @nestjs/serve-static
for the latest version(2.2.2
) and found a dependency on fastify-static
. Is @nestjs/serve-static
being updated or scheduled to be updated. If so, when will I be able to use it?
Publish updates dependent on @fastify/static
instead.
No response
Migrating nestjs from v8 to v9
[ ] Regression
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
It seems that it is not possible to prevent caching of one file
I would like to prevent caching of my index.html file but cache all other assets such as css and js files
I am serving an angular app. All generated files have a hash in the name so they care fine be cached as the name will change between versions. At the moment the index page is cached and it's very hard to get a new version loaded onto a mobile browser. Turning off caching for index.html will mean I get new app versions on mobile browsers but that the large asset files will be cached.
ServeStaticOptions interface defined in @nestjs/platform-express has an extra property 'prefix' which is missing from the same interface defined in this package. Having the option within this module would be great and shouldn't we define the interface once unless there is a special reason for having a duplicate in this package as well?
A deprecated warning get triggered when we use "@nestjs/serve-static": "2.2.2"
https://gist.github.com/SteadEXE/2220524c25cbd59ab04ce5d772d7b56e
No warning in the console
2.2.2
8.4.5
16.15.0
(node:13584) [FST_MODULE_DEP_FASTIFY-STATIC] FastifyWarning.fastify-static: fastify-static has been deprecated. Use @fastify/[email protected] instead.
(Use node --trace-warnings ...
to show where the warning was created)
[ ] Regression
[ ] Bug report
[*] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
It does not seem to be possible with this module.
There is option to enable livereload. See Browsersync for reference.
It will help a lot.
[ ] Regression
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
So if you setup the ServeStaticModule and provide serveStaticOptions: { fallthrough: false }, the module reports a 500 (Internal Server) error.
I don't know why this is not coming clearly to me, but I want to change the 500 error to a 404, because the file was not found.
I tried to use a global Internal Server filter and match the route in the case of 500 errors, but that wasn't possible because for some reason the filter doesn't get hit. I must be missing something higher level about NestJS.
I expect there to be an ergonomic way to handle errors when fallthrough is set to false.
Use the example in the nest repo: https://github.com/nestjs/nest/blob/master/sample/24-serve-static/src/app.module.ts#L8
and configure your ServeStaticModule to also serve your home directory (just an example) include serveStaticOptions: { fallthrough: false }
. Then after you have set up the mount point, start the server and enter a URL under the mount point that would not exist in your home directory. Your browser should report a 500 error.
It currently seems either impossible or not easily discoverable on how a developer can catch the serve-static 500 error and change it to a 404 for when a file is not found.
Nest version: 7.0.2
Honestly maybe this is an issue for the serve-static repo. I am unsure.
'''
2 import { ServeStaticModule } from '@nestjs/serve-static';
'''
src/app.module.ts:2:10 - error TS2305: Module '"@nestjs/serve-static"' has no exported member 'ServeStaticModule
https://i.imgur.com/YP4gMrS.png
It seems that the static module have a problem.
https://gist.github.com/bussiere/c1ed49fdb9edb9eda64eebb5b9052878
npm install @nestjs/serve-static
and use
'''
import { ServeStaticModule } from '@nestjs/serve-static';
'''
that ServeStaticModule can be imported.
github:nestjs/serve-static
8.2.2
v17.5.0
No response
Expose a function to transform the index.html
before sending it to the client to inject some variables or replace certain parts, without setting up a complete view engine
setup.
It would be great to expose a function transformIndexHtml?: (indexHtml: string)=> string | Promise<string>
With this function any transform can be handled.
Here is the diff file I use to patch-package
this feature in our code base:
diff --git a/node_modules/@nestjs/serve-static/dist/interfaces/serve-static-options.interface.d.ts b/node_modules/@nestjs/serve-static/dist/interfaces/serve-static-options.interface.d.ts
index a996aff..e1dd974 100644
--- a/node_modules/@nestjs/serve-static/dist/interfaces/serve-static-options.interface.d.ts
+++ b/node_modules/@nestjs/serve-static/dist/interfaces/serve-static-options.interface.d.ts
@@ -5,6 +5,7 @@ export interface ServeStaticModuleOptions {
renderPath?: string | RegExp;
serveRoot?: string;
exclude?: string[];
+ transformIndexHtml?: (indexHtml: string) => string;
serveStaticOptions?: {
cacheControl?: boolean;
dotfiles?: string;
diff --git a/node_modules/@nestjs/serve-static/dist/loaders/express.loader.js b/node_modules/@nestjs/serve-static/dist/loaders/express.loader.js
index 75c9f9b..d447522 100644
--- a/node_modules/@nestjs/serve-static/dist/loaders/express.loader.js
+++ b/node_modules/@nestjs/serve-static/dist/loaders/express.loader.js
@@ -29,7 +29,19 @@ let ExpressLoader = class ExpressLoader extends abstract_loader_1.AbstractLoader
const stat = fs.statSync(indexFilePath);
options.serveStaticOptions.setHeaders(res, indexFilePath, stat);
}
- res.sendFile(indexFilePath);
+ if(options.transformIndexHtml != null) {
+ fs.readFile(indexFilePath, 'utf8', (err, data) => {
+ if (err) {
+ next(err);
+ return;
+ }
+ const transformed = options.transformIndexHtml(data);
+ res.set('Content-Type', 'text/html');
+ res.send(transformed);
+ })
+ } else {
+ res.sendFile(indexFilePath);
+ }
}
else {
next();
No response
We want to inject a variables into the index.html
before sending it to the client. In our case we want to replace the <base href="/"/>
with the correct baseUrl
in case the application runs on a pathname e.g. http://localhost:3001/app
. Additionally we want to set a variable on the window
object. We don't want to setup the whole view engine and install something like ejs
to do these simple transformations.
If I set :
ServeStaticModule.forRoot({
rootPath: path.resolve(__dirname, 'static'),
serveStaticOptions: {
index: false
}
})
I still get error in console:
ENOENT: no such file or directory, stat '/../dist/static/index.html'
"@nestjs/serve-static": "2.2.2",
"@nestjs/common": "7.6.15",
"@nestjs/config": "0.6.3",
"@nestjs/core": "7.6.15",
[x] Regression
[ ] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
When running e2e tests, @nestjs/serve-static uses noop loader.
Consequently, my tests for routing are failing because serve-static returns a 404 error on non-existing routes, instead of serving the index.html of the root folder.
With version 2.1.0, when running e2e tests serve-static was using express loader instead of noop loader. So when requesting http://myserver/non-existing-path serve-static was returning a response 200 with /index.html as content.
The culprit is this commit : db6e86d#diff-b38ccc22d6bb4ce4c12a2c61b89a974b
Testing the routing of @nestjs/serve-static should be possible.
Doing the same with @nestjs/serve-static 2.1.0 will succeed
Nest version: 7.1.3
For Tooling issues:
- Node version: 12.16.2
- Platform: Linux
[ ] Regression
[ ] Bug report
[ ] Feature request
[ x] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
I'm currently pointing a few subdomains to the same server. All of the subdomains are using the same backend and I was wondering if I can serve different frontends for each of the subdomains.
I know that it's possible using express-subdomain for express:
const subdomain = require('express-subdomain')
const subRouter = express.Router()
subRouter.use('/', express.static(path.join(__dirname, '/../subfrontend/build')))
subRouter.get('/*', (req, res) => {
res.sendFile(path.join(__dirname, '/../subfrontend/build/index.html`))
})
app.use(subdomain('sub', subRouter))
Is this currently possible to implement using @nestjs/serve-static?
Each of the subdomains will be served with different frontend
Nest version: 7.1.3
For Tooling issues:
- Node version: 12.16.2
- Platform: Linux
There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.
Error type: undefined. Note: this is a nested preset so please contact the preset author if you are unable to fix it yourself.
[ ] Regression
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
When using the @nestjs/serve-static
module, the server serves any path and does not return a 404 error even if the requested resource does not exist.
.
βββ client
β βββ index.hml
βββ src
β βββ app.module.ts
// src\app.module.ts
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';
imports: [
ServeStaticModule.forRoot({ rootPath: join(process.cwd(), 'client') })
],
Request an existing resource
GET / HTTP/1.1
Host: localhost:3000
Response
HTTP/1.1 200 OK
Request a nonexistent resource
GET /foo HTTP/1.1
Host: localhost:3000
Response
HTTP/1.1 200 OK
Request a nonexistent resource
GET /foo HTTP/1.1
Host: localhost:3000
Response
HTTP/1.1 404 Not Found
nest new testcase
npm install --save @nestjs/serve-static
ServeStaticModule.forRoot({ rootPath: join(process.cwd(), 'client') })
in app.module.ts
testcase/client
index.html
under the testcase/client
npm run start
curl --location --request GET 'localhost:3000/foo'
HTTP/1.1 200 OK
but expected HTTP/1.1 404 Not Found
In general, "serve-static" should follow the usual logic while serving files. If requested resource does not exists, an error is returned. Or in documentation should have a place where described this behavior and provided some instruction for handling that situations.
Nest version: 7.2.0
For Tooling issues:
- Node version: v12.16.3
- Platform: Windows
Others:
No response
2.2.2 -> 3.0.1
Excluded paths that were not found would return a 404. It now fallbacks to index.html
This test was successful on 2.x
it('should return 404 for static assets (eg .js, .svg, ..., which were not found', async () => {
return request(app.getHttpServer()).get('/app-bad-name.js').expect(404);
});
Here is the configuration we use :
imports: [
ServeStaticModule.forRoot({
// note: this isn't trying to be an exhaustive list of possible assets
// we just want to handle the most common ones
exclude: ['/*.(js|css|eot|ttf|woff|gif|ico|png|svg|jpg)'],
rootPath,
serveStaticOptions: {
maxAge: MAX_AGE_7_DAYS,
setHeaders: (res, path) => {
if (path.endsWith('index.html')) {
// use .setHeader
}
}
}
The application fall backs to index.html
when a stati
Excluded path should return a 404
I see that you use path-to-regexp 0.3.5 in your package... it's a bit weird because on our side, when i was building against next@8, I ended up with path-to-regexp 3.x, and when I was building against next@9, I endep up with path-to-regexp 6.x. So something might be wrong on my side too
[ ] Regression
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
Simple serve-static
Provides a small layer on top of serve-static, which allows to serve pre-gzipped files. Supports brotli and allows configuring any other compression you can think of as well.
see https://github.com/tkoenig89/express-static-gzip
Nest version: X.Y.Z
For Tooling issues:
- Node version: XX
- Platform:
Others:
[ ] Regression
[x ] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
If StaticServer imported with "renderPath" option it doesn't serve assets on /static
StaticServer should provide all the assets on /static
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';
@Module({
imports: [
ServeStaticModule.forRoot({
rootPath: join(__dirname, 'public'),
renderPath: "/static"
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
I would suggest to edit express.loader.ts file according to Express mount path specification.
Replace
const clientPath = options.rootPath;
const indexFilePath = this.getIndexFilePath(clientPath);
app.use(express.static(clientPath, options.serveStaticOptions));
app.get(options.renderPath, (req: any, res: any) =>
res.sendFile(indexFilePath)
);
with
const clientPath = options.rootPath;
app.use(options.renderPath, express.static(clientPath, options.serveStaticOptions));
What are the benefits of serve-static?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.