I have created app using reactjs, nodejs(restify) and postgresql, I build successfully on Heroku but when i open my app I am getting error {"code":"ResourceNotFound","message":"/ does not exist"} I am try to add serverStaticFiles() but it gives me AssertionError [ERR_ASSERTION]: directory (string) is required so I removed it now Now help me to find what i did wrong here...
Server.js
var restify=require('restify')
const { logIn,userCreation, demotable } = require('./routes/Function');
const corsMiddleware = require('restify-cors-middleware2');
const { data } = require('jquery');
const PORT=process.env.PORT || 8080;
var path=require('path')
var server=restify.createServer() //server created
server.use(
function crossOrigin(req,res,next){
res.header("Access-Control-Allow-Origin", "*");
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
res.setHeader('Access-Control-Allow-Credentials', true); // If needed
res.header("Access-Control-Allow-Origin", "*");
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
return next();
}
);
const cors = corsMiddleware({
preflightMaxAge: 5, //Optional
origins: ['*'],
allowHeaders: ['*'],
exposeHeaders: ['*']
})
server.pre(cors.preflight)
server.use(cors.actual)
//setting
// if (process.env.NODE_ENV === "production") {
// //server static content
// //npm run build
// server.use(restify.static(path.join(__dirname, "client/build")));
// }
console.log(__dirname);
console.log(path.join(__dirname, "client/build"));
//get data from login form
server.post('/note', userCreation);
server.use(restify.plugins.bodyParser());
server.get('/login',logIn)
server.get('/employees',demotable)
if(process.env.NODE_ENV==='production')
{
server.get('/client/build/*', restify.plugins.serveStatic({
directory: __dirname,
default: 'index.html'
}));
// server.use(restify.serveStatic('client/build'))
// server.get('*',(req,res)=>{
// res.sendFile(path.join(__dirname,'client','build','index.html'))
// })
}
// server.get("*", (req, res) => {
// res.sendFile(path.join(__dirname, "client/build/index.html"));
// });
server.listen(PORT, function(){
console.log("server started...")
})
package.json
{
"name": "backend",
"version": "1.0.0",
"engines": {
"npm": "6.x",
"node": "12.18.2"
},
"description": "",
"main": "index.js",
"start": "node Server.js",
"heroku-postbuild": "cd client && npm install && npm run build",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node Server.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"dotenv": "^8.2.0",
"jquery": "^3.5.1",
"pg": "^8.3.0",
"pg-hstore": "^2.3.3",
"restify": "^8.5.1",
"restify-cors-middleware2": "^2.1.0",
"sequelize": "^6.3.3"
},
"devDependencies": {
"nodemon": "^2.0.4"
}
}
You should put the "start": "node server.js" inside the scripts section like
"scripts": {
"start": "node server.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
Related
In my project, I'm using the reanimate library to add animations, but I'm receiving an error
https://stackoverflow.com/questions/63005011/support-for-the-experimental-syntax-jsx-isnt-currently-enabled
I follow all the steps mention in the link but none of them work for me
My package.json file
{
"name": "animation",
"version": "0.1.0",
"private": true,
"dependencies": {
"#react-spring/native": "^9.6.1",
"#react-spring/web": "^9.6.1",
"#testing-library/jest-dom": "^5.16.5",
"#testing-library/react": "^13.4.0",
"#testing-library/user-event": "^13.5.0",
"babel-polyfill": "^6.26.0",
"lodash": "^4.17.21",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-native-reanimated": "^2.14.4",
"react-native-web": "^0.18.10",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"#babel/plugin-syntax-jsx": "^7.18.6",
"#babel/preset-env": "^7.20.2",
"#babel/preset-react": "^7.18.6",
"babel-loader": "^9.1.2",
"url-loader": "^4.1.1",
"webpack": "^5.75.0",
"webpack-cli": "^5.0.1",
"webpack-dev-server": "^4.11.1"
}
}
webpack.config.js
// web/webpack.config.js
const path = require("path");
const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const appDirectory = path.resolve(__dirname, "../");
// This is needed for webpack to compile JavaScript.
// Many OSS React Native packages are not compiled to ES5 before being
// published. If you depend on uncompiled packages they may cause webpack build
// errors. To fix this webpack can be configured to compile to the necessary
// `node_module`.
const babelLoaderConfiguration = {
test: /\.js$/,
// Add every directory that needs to be compiled by Babel during the build.
include: [
path.resolve(appDirectory, "index.web.js"),
path.resolve(appDirectory, "src"),
path.resolve(appDirectory, "node_modules/react-native-uncompiled"),
],
use: {
loader: "babel-loader",
options: {
cacheDirectory: true,
// The 'metro-react-native-babel-preset' preset is recommended to match React Native's packager
presets: [
"#babel/preset-react",
"module:metro-react-native-babel-preset",
],
// Re-write paths to import only the modules needed by the app
plugins: [
"#babel/plugin-syntax-jsx",
"react-native-web",
"react-native-reanimated/plugin",
],
},
},
};
// This is needed for webpack to import static images in JavaScript files.
const imageLoaderConfiguration = {
test: /\.(gif|jpe?g|png|svg)$/,
use: {
loader: "url-loader",
options: {
name: "[name].[ext]",
esModule: false,
},
},
};
module.exports = {
entry: [
// load any web API polyfills
path.resolve(appDirectory, "polyfills-web.js"),
// your web-specific entry file
path.resolve(appDirectory, "index.web.js"),
],
// configures where the build ends up
output: {
filename: "bundle.web.js",
path: path.resolve(appDirectory, "dist"),
},
// ...the rest of your config
plugins: [
new HtmlWebpackPlugin({
filename: "index.html",
template: "./index.html",
}),
new webpack.EnvironmentPlugin({ JEST_WORKER_ID: null }),
new webpack.DefinePlugin({ process: { env: {} } }),
],
module: {
rules: [babelLoaderConfiguration, imageLoaderConfiguration],
},
resolve: {
// This will only alias the exact import "react-native"
alias: {
"react-native$": "react-native-web",
},
// If you're working on a multi-platform React Native app, web-specific
// module implementations should be written in files using the extension
// `.web.js`.
extensions: [".web.js", ".js"],
},
};
I am deploying my MERN application to Heroku. The build is successful but when I open my application the web page shows application error. I checked logs but couldn't understand much from that.
This is my first deployment of an MERN application, so please guide me. Thankyou.
These are the logs
server.js
const express = require('express');
const connectDB = require('./config/database');
const path = require('path');
const app = express();
const PORT = process.env.PORT || 5000;
// Connect Database
connectDB();
// Init Middleware
app.use(express.json({extended: false}));
// Defining Routes
app.use('/api/users', require('./routes/users'));
app.use('/api/contacts', require('./routes/contacts'));
app.use('/api/auth', require('./routes/auth'));
// Serve static assets in production
if(process.env.NODE_ENV === 'production') {
// Set static folder
app.use(express.static('client/build'));
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'));
})
}
app.listen(PORT, () => {
console.log(`Server started on port ${PORT}`);
});
server's package.json
{
"name": "contact-keeper",
"version": "1.0.0",
"description": "Contact Manager App",
"main": "server.js",
"scripts": {
"start": "node server.js",
"server": "nodemon server.js",
"client": "npm start --prefix client",
"clientinstall": "npm install --prefix client",
"dev": "concurrently \"npm run server\" \"npm run client\"",
"test": "echo \"Error: no test specified\" && exit 1",
"heroku-postbuild": "NPM_CONFIG_PRODUCTION=false npm install --prefix client && npm run build --prefix client"
},
"engines": {
"node": "12.18.3"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"bcrypt": "^5.0.1",
"config": "^3.3.6",
"express": "^4.17.1",
"express-validator": "^6.12.1",
"jsonwebtoken": "^8.5.1",
"mongoose": "^5.13.4"
},
"devDependencies": {
"concurrently": "^6.2.0",
"nodemon": "^2.0.12"
}
}
I am having a simple Fastify server hosted with Heroku. But, it seems not working ! But, it seemed all right during the development! The error I get is: Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch. Full error I am getting:
Here is the code I am using:
server.js:
const fastify = require("fastify")();
const path = require("path");
fastify.register(require("fastify-static"), {
root: path.join(__dirname, "/"),
});
fastify.get("/", function (req, reply) {
reply.sendFile("index.html");
});
fastify.listen(process.env.PORT || 5000, (err) => {
if (err) throw err;
console.log(`server listening on ${fastify.server.address().port}`);
});
package.json:
{
"name": "test1",
"version": "1.0.0",
"description": "",
"main": "server.js",
"engines": {
"node": "15.11.x"
},
"scripts": {
"start": "node server.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"fastify": "^3.14.0",
"fastify-static": "^4.0.1"
}
}
Sometimes, the site even doesn't load!
Any help is greatly appreciated !
Thanks !
That's an issue with the library. For other libraries (express, django, etc..) specifying the address is not necessary.
See https://github.com/fastify/fastify/issues/709
Change:
.listen(process.env.PORT)
to:
.listen(process.env.PORT, '0.0.0.0')
When I use both nodemon as local server and Heroku for production the following works for me:
await fastify.listen(process.env.PORT, process.env.HOST || '0.0.0.0');
and in package.json
"dev": "PORT=${PORT:=3000} HOST=${HOST:=localhost} nodemon"
I'm using Webpack 5 and Angular 11
when I execute the command
ng build --prod && ng run test-app:server:production
In the console it gives me an error message:
Error: ./node_modules/msnodesqlv8/build/Release/sqlserverv8.node 1:2
Module parse failed: Unexpected character '�' (1:2)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
and directory is not being built: dist/test-app/server/main.js it only creates itself: dist/test-app/browser/
I don't know where I have badly configured files.
Please help. I don't know what I'm doing wrong.
package.json:
{
"name": "test-app",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
"dev:ssr": "ng run test-app:serve-ssr",
"serve:ssr": "node dist/test-app/server/main.js",
"build:ssr": "ng build --prod && ng run test-app:server:production",
"prerender": "ng run test-app:prerender",
"start-webpack:server": "webpack --config webpack.server.config.js "
},
"private": true,
"resolution": {
"webpack": "^5.0.0"
},
"dependencies": {
"#angular/animations": "~11.0.5",
"#angular/common": "~11.0.5",
"#angular/compiler": "~11.0.5",
"#angular/core": "~11.0.5",
"#angular/forms": "~11.0.5",
"#angular/platform-browser": "~11.0.5",
"#angular/platform-browser-dynamic": "~11.0.5",
"#angular/platform-server": "^11.0.7",
"#angular/router": "~11.0.5",
"#nguniversal/express-engine": "^11.0.1",
"express": "^4.17.1",
"msnodesqlv8": "^2.0.8",
"mssql": "^6.3.1",
"rxjs": "~6.6.0",
"tslib": "^2.0.0",
"zone.js": "~0.10.2"
},
"devDependencies": {
"#angular-devkit/build-angular": "~0.1100.5",
"#angular/cli": "~11.0.5",
"#angular/compiler-cli": "~11.0.5",
"#nguniversal/builders": "^11.0.1",
"#types/express": "^4.17.9",
"#types/jasmine": "~3.6.0",
"#types/node": "^12.11.1",
"codelyzer": "^6.0.0",
"jasmine-core": "~3.6.0",
"jasmine-spec-reporter": "~5.0.0",
"karma": "~5.1.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage": "~2.0.3",
"karma-jasmine": "~4.0.0",
"karma-jasmine-html-reporter": "^1.5.0",
"protractor": "~7.0.0",
"ts-loader": "^8.0.14",
"ts-node": "^8.3.0",
"tslint": "~6.1.0",
"typescript": "~4.0.2",
"webpack-cli": "^4.3.1"
},
"description": "This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 11.0.5.",
"main": "karma.conf.js",
"keywords": [],
"author": "",
"license": "ISC"
}
angular.json:
{
"$schema": "./node_modules/#angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"test-app": {
"projectType": "application",
"schematics": {
"#schematics/angular:component": {
"style": "scss"
},
"#schematics/angular:application": {
"strict": true
}
},
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {
"builder": "#angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/test-app/browser",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"aot": true,
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.scss"
],
"scripts": []
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"namedChunks": false,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "6kb",
"maximumError": "10kb"
}
]
}
}
},
"serve": {
"builder": "#angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "test-app:build"
},
"configurations": {
"production": {
"browserTarget": "test-app:build:production"
}
}
},
"extract-i18n": {
"builder": "#angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "test-app:build"
}
},
"test": {
"builder": "#angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.spec.json",
"karmaConfig": "karma.conf.js",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.scss"
],
"scripts": []
}
},
"lint": {
"builder": "#angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"tsconfig.app.json",
"tsconfig.spec.json",
"e2e/tsconfig.json",
"tsconfig.server.json"
],
"exclude": [
"**/node_modules/**"
]
}
},
"e2e": {
"builder": "#angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "test-app:serve"
},
"configurations": {
"production": {
"devServerTarget": "test-app:serve:production"
}
}
},
"server": {
"builder": "#angular-devkit/build-angular:server",
"options": {
"outputPath": "dist/test-app/server",
"main": "server.ts",
"tsConfig": "tsconfig.server.json"
},
"configurations": {
"production": {
"outputHashing": "media",
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"sourceMap": false,
"optimization": true
}
}
},
"serve-ssr": {
"builder": "#nguniversal/builders:ssr-dev-server",
"options": {
"browserTarget": "test-app:build",
"serverTarget": "test-app:server"
},
"configurations": {
"production": {
"browserTarget": "test-app:build:production",
"serverTarget": "test-app:server:production"
}
}
},
"prerender": {
"builder": "#nguniversal/builders:prerender",
"options": {
"browserTarget": "test-app:build:production",
"serverTarget": "test-app:server:production",
"routes": [
"/"
]
},
"configurations": {
"production": {}
}
}
}
}
},
"defaultProject": "test-app",
"cli": {
"analytics": "e9a52f4c-af8d-4030-8d24-ba3f4b17ec39"
}
}
server.ts:
import 'zone.js/dist/zone-node';
import { ngExpressEngine } from '#nguniversal/express-engine';
import * as express from 'express';
import { join } from 'path';
import { AppServerModule } from './src/main.server';
import { APP_BASE_HREF } from '#angular/common';
import { existsSync } from 'fs';
import { TestRoute } from './server/router/test';
const testRoute: TestRoute = new TestRoute();
export function app(): express.Express {
const server = express();
const distFolder = join(process.cwd(), 'dist/test-app/browser');
const indexHtml = existsSync(join(distFolder, 'index.original.html')) ? 'index.original.html' : 'index';
server.engine('html', ngExpressEngine({
bootstrap: AppServerModule,
}));
server.set('view engine', 'html');
server.set('views', distFolder);
server.get('*.*', express.static(distFolder, {
maxAge: '1y'
}));
server.get('*', (req, res) => {
res.render(indexHtml, { req, providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }] });
});
return server;
}
function run(): void {
const port = process.env.PORT || 4000;
const server = app();
server.listen(port, () => {
console.log(`Node Express server listening on http://localhost:${port}`);
});
}
// Webpack will replace 'require' with '__webpack_require__'
// '__non_webpack_require__' is a proxy to Node 'require'
// The below code is to ensure that the server is run only when not requiring the bundle.
declare const __non_webpack_require__: NodeRequire;
const mainModule = __non_webpack_require__.main;
const moduleFilename = mainModule && mainModule.filename || '';
if (moduleFilename === __filename || moduleFilename.includes('iisnode')) {
run();
}
export * from './src/main.server';
commented out on this line of code:
const testRoute: TestRoute = new TestRoute();
and execute the command
ng build --prod && ng run test-app: server: production
does not display errors.
The TestRoute class contains a reference to the library and connecting to the database:
import { Request, Response, NextFunction, response } from 'express';
export class TestRoute {
contractorRoute(app: any): void {
app.route('/api/get-test').get((req: Request, res: Response, next: NextFunction) => {
var sql = require("mssql/msnodesqlv8");
let config = {
server: 'SQLDXXX\\XXX',
database: 'XXX',
driver: "msnodesqlv8",
options: {
trustedConnection: true
}
};
let connect = new sql.ConnectionPool(config);
connect.connect().then(() => {
connect.request().query('select * from [test].[dbo].[test]', (err: TypeError, recordset: any) => {
if (err) {
console.error(" Error: " + err );
return;
} else {
res.send(recordset);
}
connect.close();
})
}).catch((err: any) => {
console.error(" Error: " + err );
});
})
}
}
tsconfig.app.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/app",
"types": [
"node"
]
},
"files": [
"src/main.ts",
"src/polyfills.ts"
],
"include": [
"src/**/*.d.ts"
]
}
tsconfig.json
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"sourceMap": true,
"declaration": false,
"downlevelIteration": true,
"experimentalDecorators": true,
"moduleResolution": "node",
"importHelpers": true,
"target": "es2015",
"module": "es2020",
"lib": [
"es2018",
"dom"
]
},
"angularCompilerOptions": {
"strictInjectionParameters": true,
"strictInputAccessModifiers": true,
"strictTemplates": true
}
}
tsconfig.server.json
{
"extends": "./tsconfig.app.json",
"compilerOptions": {
"outDir": "./out-tsc/app",
"target": "es2020",
"module": "commonjs",
"types": [
"node"
]
},
"files": [
"src/main.server.ts",
"server.ts"
],
"angularCompilerOptions": {
"entryModule": "./src/app/app.server.module#AppServerModule"
}
}
webpack.server.config.js
const path = require("path");
const webpack = require("webpack");
module.exports = {
entry: { server: "./server.ts" },
resolve: { extensions: [".js", ".ts"] },
target: "node",
mode: "none",
// this makes sure we include node_modules and other 3rd party libraries
externals: [/node_modules/],
output: {
path: path.join(__dirname, "dist"),
filename: "[name].js"
},
module: {
rules: [
{ test: /\.ts$/, loader: "ts-loader" },
{ test: /\.node$/, use: "node-loader" },
]
},
plugins: [
// Temporary Fix for issue: https://github.com/angular/angular/issues/11580
// for 'WARNING Critical dependency: the request of a dependency is an expression'
new webpack.ContextReplacementPlugin(
/(.+)?angular(\\|\/)core(.+)?/,
path.join(__dirname, "src"), // location of your src
{} // a map of your routes
),
new webpack.ContextReplacementPlugin(
/(.+)?express(\\|\/)(.+)?/,
path.join(__dirname, "src"),
{}
)
]
};
the documentation https://www.npmjs.com/package/msnodesqlv8 says about adding a line I added it:
{ test: /\.node$/, use: 'node-loader' }
but the error is still there:
Error: ./node_modules/msnodesqlv8/build/Release/sqlserverv8.node 1:2
Module parse failed: Unexpected character '�' (1:2)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
I don't know what else I should improve.
Thank you for your help
the application example is based on:
https://www.ganatan.com/tutorials/server-side-rendering-with-angular-universal
I have created a new dotnet core project using yeoman in osx. So, It didn't have package.json and gulpfile.js. I've added them manually
I have delete main.css & main.min.css file ./wwwroot/css because I'm writing all my styles in scss so it would automatically generate .css files
But, in this case nothing happens. No .css get generated & scss styles doesn't works
When build my project & run it with dotnet run command after editing sass file nothing happens. No css file gets generated
./wwwroot/styles/scss/main2.scss
$base: #CC0000;
body {
background-color: $base;
}
package.json
{
"devDependencies": {
"gulp": "3.8.11",
"gulp-concat": "2.5.2",
"gulp-cssmin": "0.1.7",
"gulp-uglify": "1.2.0",
"rimraf": "2.2.8",
"gulp-sass": "1.3.3"
}
}
gulpfile.js
/// <binding Clean='clean' />
"use strict";
var gulp = require("gulp"),
rimraf = require("rimraf"),
concat = require("gulp-concat"),
cssmin = require("gulp-cssmin"),
uglify = require("gulp-uglify"),
sass = require("gulp-sass");
var paths = {
webroot: "./wwwroot/"
};
paths.js = paths.webroot + "js/*.js";
paths.minJs = paths.webroot + "js/*.min.js";
paths.css = paths.webroot + "css/*.css";
paths.minCss = paths.webroot + "css/*.min.css";
paths.concatJsDest = paths.webroot + "js/site.min.js";
paths.concatCssDest = paths.webroot + "css/site.min.css";
gulp.task("sass", function() {
return gulp.src("./wwwroot/styles/scss/main2.scss")
.pipe(sass())
.pipe(gulp.dest(project.webroot + '/css'));
});
gulp.task("clean:js", function(cb) {
rimraf(paths.concatJsDest, cb);
});
gulp.task("clean:css", function(cb) {
rimraf(paths.concatCssDest, cb);
});
gulp.task("clean", ["clean:js", "clean:css"]);
gulp.task("min:js", function() {
return gulp.src([paths.js, "!" + paths.minJs], { base: "." })
.pipe(concat(paths.concatJsDest))
.pipe(uglify())
.pipe(gulp.dest("."));
});
gulp.task("min:css", function() {
return gulp.src([paths.css, "!" + paths.minCss])
.pipe(concat(paths.concatCssDest))
.pipe(cssmin())
.pipe(gulp.dest("."));
});
gulp.task("min", ["min:js", "min:css"]);
project.json
{
"dependencies": {
"Microsoft.NETCore.App": {
"version": "1.1.0",
"type": "platform"
},
"Microsoft.AspNetCore.Diagnostics": "1.1.0",
"Microsoft.AspNetCore.Mvc": "1.1.0",
"Microsoft.AspNetCore.Razor.Tools": {
"version": "1.1.0-preview4-final",
"type": "build"
},
"Microsoft.AspNetCore.Routing": "1.1.0",
"Microsoft.AspNetCore.Server.IISIntegration": "1.1.0",
"Microsoft.AspNetCore.Server.Kestrel": "1.1.0",
"Microsoft.AspNetCore.StaticFiles": "1.1.0",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.1.0",
"Microsoft.Extensions.Configuration.Json": "1.1.0",
"Microsoft.Extensions.Configuration.CommandLine": "1.1.0",
"Microsoft.Extensions.Logging": "1.1.0",
"Microsoft.Extensions.Logging.Console": "1.1.0",
"Microsoft.Extensions.Logging.Debug": "1.1.0",
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.1.0",
"Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.1.0"
},
"tools": {
"BundlerMinifier.Core": "2.2.306",
"Microsoft.AspNetCore.Razor.Tools": "1.1.0-preview4-final",
"Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.1.0-preview4-final"
},
"frameworks": {
"netcoreapp1.1": {
"imports": [
"dotnet5.6",
"portable-net45+win8"
]
}
},
"buildOptions": {
"emitEntryPoint": true,
"preserveCompilationContext": true
},
"runtimeOptions": {
"configProperties": {
"System.GC.Server": true
}
},
"publishOptions": {
"include": [
"wwwroot",
"**/*.cshtml",
"appsettings.json",
"web.config"
]
},
"scripts": {
"precompile": ["dotnet bundle"],
"prepublish": [
"npm install",
"bowser install",
"gulp clean",
"gulp min"
],
"postpublish": ["dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%"],
"prebuild": "gulp sass",
"postbuild": "echo after building",
"prepack": "echo before packing",
"postpack": "echo after packing",
"prerestore": "echo before restoring packages",
"postrestore": "echo after restoring packages"
},
"tooling": {
"defaultNamespace": "Sample"
}
}
after changing "precompile": ["gulp sass"]
$
dotnet run
Project Sample (.NETCoreApp,Version=v1.1) will be compiled because project is not safe for incremental compilation. U
se --build-profile flag for more information.
Compiling Sample for .NETCoreApp,Version=v1.1
[08:50:23] Warning: gulp version mismatch:
[08:50:23] Global gulp is 3.9.1
[08:50:23] Local gulp is 3.8.11
[08:50:23] Using gulpfile ~/Unity3D/DotNetCore/Sample/gulpfile.js
[08:50:23] Starting 'sass'...
[08:50:23] Finished 'sass' after 19 ms
Compilation succeeded.
0 Warning(s)
0 Error(s)
Please try the following 2 ideas:
Add a "precompile" script to the scripts section of your project.json file which invokes the gulp sass task:
"precompile": ["gulp sass"]
Change your gulp sass task to the following:
gulp.task("sass", function() {
return gulp.src("./wwwroot/styles/scss/main2.scss")
.pipe(sass())
.pipe(gulp.dest(paths.webroot + '/css'));
});
The task currently references a variable named project, which doesn't exist.
Also, to fix the gulp version mismatch warning, run the following from a command shell from the directory in which your package.json file lives:
npm i -D gulp#3.9.1
Alternatively, you could just change the 3.8.11 version number for gulp in your package.json file to 3.9.1.
I solved this issue from another angle as I was unable to get the above running with a dotnetcore 2.0 application.
Initially I tried the recommended approach from Microsoft: https://learn.microsoft.com/en-us/aspnet/core/client-side/using-gulp?view=aspnetcore-2.1 and convert the project.json file with the changes suggested by #Scott Addie into an XML syntax supported in the csproj file. Looks something like this:
<Target Name="MyPreCompileTarget" BeforeTargets="Build">
<Exec Command="gulp frontend" ContinueOnError="false" />
</Target>
But, depending on the logic inside your gulpfile.js, this sometimes refused to run. In my case it seemed to fail on filewatchers like this one:
gulp.watch('./frontend/source/javascript/**/*.js', ['compileJs']);
So I ended up apporaching it the other way around. Start the sass compilation tool from my gulpfile.js and then from within the gulpfile.js start the dotnet process. Something like this:
/**
* NodeJS Gulp tasks for "compiling" frontend files and start potentially start the dotnetcore application
*/
const gulp = require('gulp');
const plumber = require('gulp-plumber');
const sass = require('gulp-sass');
const runSequence = require('run-sequence').use(gulp);
const minifyCss = require('gulp-minify-css');
const notifier = require('node-notifier');
const browserify = require('browserify');
const source = require('vinyl-source-stream');
const buffer = require('vinyl-buffer');
const sourcemaps = require('gulp-sourcemaps');
const path = require('path');
const uglify = require('gulp-uglify');
const rename = require('gulp-rename');
const livereload = require('gulp-livereload');
var spawn = require('child_process').spawn;
var fancyLog = require('fancy-log');
var beeper = require('beeper');
// Port that livereload is listening to
const liveReloadPort = 5812;
/**
* Initialize the basic tasks for compiling front-end assets
*/
gulp.task('frontend', function () {
return runSequence(
'compileJs',
'compileSass',
'watch',
'livereload')
})
/**
* Initialize tasks for compiling front-end assets and runs dotnet in watch mode as well
*/
gulp.task('dotnet', function () {
return runSequence(
'compileJs',
'compileSass',
'watch',
'livereload',
function () {
//
// Start the dotnet core process
//
const child = spawn("dotnet", ["watch", "run"], {
cwd: process.cwd()
})
let stdout = '';
let stderr = '';
child.stdout.setEncoding('utf8');
child.stdout.on('data', function (data) {
stdout += data;
console.log(data);
});
child.stderr.setEncoding('utf8');
child.stderr.on('data', function (data) {
stderr += data;
fancyLog.error(data);
beeper();
});
child.on('close', function (code) {
fancyLog("Done with exit code", code);
fancyLog("You access complete stdout and stderr from here"); // stdout, stderr
});
});
})
/**
* Starts the livereload tool
*/
gulp.task('livereload', function () {
// Start livereload
console.log('* Starting livereload on port: ' + liveReloadPort);
livereload.listen(5812);
})
/**
* Watches the filesystem and initializes the tasks when a file has been changed
*/
gulp.task('watch', function () {
// 1) Compile the client-side JavaScript file when one of the source files changes
gulp.watch('./frontend/source/javascript/**/*.js', ['compileJs']);
// 2) Compile the client-side CSS file when one of the source SASS files changes
gulp.watch('./frontend/source/stylesheets/*.scss', ['compileSass']);
});
/**
* Compiles SASS files and stores the result into the public folder
*/
gulp.task('compileSass', function () {
return gulp.src('./frontend/source/stylesheets/main.scss')
.pipe(plumber())
.pipe(sass().on('error', function (err) {
console.log('SASS compile error: ', err.toString());
notifier.notify({
'title': 'SASS Compile Error',
'message': err.message
});
this.emit("end");
}))
.pipe(gulp.dest('./frontend/public/stylesheets'))
.pipe(minifyCss({
compatibility: 'ie8'
}))
.pipe(rename({
suffix: '.min'
}))
.pipe(gulp.dest('./frontend/public/stylesheets'))
.pipe(livereload());
});
/**
* Compiles the Javascript files and stores the result in the public folder
*/
gulp.task('compileJs', function () {
return browserify(path.resolve('./frontend/source/javascript', 'app.js'))
.bundle()
.on('error', function (err) {
console.log('JS/Browserify error:', err.toString());
notifier.notify({
'title': 'JS Compile Error',
'message': err.message
});
this.emit("end");
})
.pipe(source('app.js'))
.pipe(buffer())
.pipe(gulp.dest('./frontend/public/javascript'))
// Create minified version of JS
.pipe(buffer())
.pipe(uglify())
.pipe(sourcemaps.init({
loadMaps: true
}))
.pipe(sourcemaps.write('./maps'))
.pipe(rename({
suffix: '.min'
}))
.pipe(gulp.dest('./frontend/public/javascript'))
.pipe(livereload());
});
Now I can start my dotnetcore application with my frontend compilation tools using gulp dotnet
To be complete, this is my package.json file:
{
"name": "",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "..."
},
"author": "...",
"license": "...",
"homepage": "...",
"devDependencies": {
"babel-core": "^6.26.3",
"babel-loader": "^7.1.4",
"babel-preset-es2015": "^6.24.1",
"babelify": "^8.0.0",
"beeper": "^1.1.1",
"browserify": "^16.2.2",
"fancy-log": "^1.3.2",
"gulp": "^3.9.1",
"gulp-livereload": "^3.8.1",
"gulp-minify-css": "^1.2.4",
"gulp-plumber": "^1.2.0",
"gulp-rename": "^1.2.3",
"gulp-sass": "^4.0.1",
"gulp-sourcemaps": "^2.6.4",
"gulp-uglify": "^3.0.0",
"node-notifier": "^5.2.1",
"path": "^0.12.7",
"run-sequence": "^2.2.1",
"vinyl-buffer": "^1.0.1",
"vinyl-source-stream": "^2.0.0",
"webpack": "^4.10.2"
},
"browserify": {
"transform": [
[
"babelify",
{
"presets": [
"es2015"
]
}
]
]
}
}