I am creating a node.js app with Express and socket.io.
I want to use SASS and I see there is a npm package for it, what I don't understand is how do I link between the SASS npm and the app and make it parse the SASS?
UPDATE:
I used SASS middleware https://github.com/andrew/node-sass installed it and included it the following way:
sass = require('node-sass');
app.configure(function(){
app.set('port', process.env.PORT || 3000);
/* other stuff */
sass.middleware({
src: __dirname + '/public/stylesheets/sass',
dest: __dirname + '/public/stylesheets',
debug: true
});
});
But it still doesn't work
You need to use the sass middleware, for example this one.
Quoting from docs:
var server = connect.createServer(
sass.middleware({
src: __dirname
, dest: __dirname + '/public'
, debug: true
}),
connect.static(__dirname + '/public')
);
in case of using express, just add:
app.use(
sass.middleware({
src: __dirname + '/sass', //where the sass files are
dest: __dirname + '/public', //where css should go
debug: true // obvious
})
);
to your app.configure() call.
Of course on production systems it's a better idea to precompile sass to css.
update
In the example above the middleware will look for sass files in __dirname + '/sass/css'. Also by default it looks for files with .scss extension. There doesn't seem to be an option to change the extension.
If you are using express-generator Then try
express --view=ejs --css=sass
Here is a solution based on various sources including the threads/comments above:
node:
var connect = require('connect');
var sass = require('node-sass');
var srcPath = __dirname + '/sass';
var destPath = __dirname + '/public/styles';
var server = connect.createServer(
sass.middleware({
src: srcPath,
dest: destPath,
debug: true,
outputStyle: 'expanded',
prefix: '/styles'
}),
connect.static(__dirname + '/public')
);
html:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="styles/main.css">
etc
file system:
rootDirectory / server.js (this is the node app)
rootDirectory / public / styles / (this is where the compiled scss files will appear)
rootDirectory / sass / main.scss
This works for me and I've forked the example at:
node-sass-example
here:
node-sass-example using prefix
Looks like implementation has changed a bit for Express. I had to do this instead:
npm install node-sass-middleware --save
then
var sass = require('node-sass-middleware');
app.use(
sass({
src: __dirname + '/sass', // Input SASS files
dest: __dirname + '/public', // Output CSS
debug: true
})
);
Related
Run directly from my local directory, this works fine. I type ‘localhost:3002’ in the browser and up pops my ‘find.html’ page. However, when I dockerise it and try the same command, it craps out complaining that macro.njk can’t be found.
Dockerfile:
FROM node:14.17.5
ENV NODE_ENV=production
WORKDIR /application
COPY ["package.json", "package-lock.json*", "./" ]
RUN npm install --production
COPY . .
CMD ["node", "app.js"]
In find.html:
{% extends "layout/layout.njk" %}
Nunjucks setup in app.js:
const express = require('express');
const path = require('path');
const nunjucks = require('nunjucks');
nunjucks.configure(['views',
path.join(__dirname, 'node_modules/motluk-frontend/'),
path.join(__dirname, 'node_modules/motluk-frontend/motluk/components/'),
path.join(__dirname, 'app/views/'),
], {
autoescape: true,
express: app,
});
// view engine setup
app.set('views', path.join(__dirname, 'app/views'));
app.set('view engine', 'html');
app.use(bodyParser.urlencoded({
extended: true,
}));
directory setup:
/app/views/layout/layout.njk
/app/views/pages/find.html
The error message I get:
Template render error: (/application/app/views/pages/find.html)
Error: template not found: input/macro.njk
[UPDATE] bundle.js was actually created in memory. The best way is to keep index.html and bundle.js (configured in webpack.config.js) in the same directory to avoid any issue.
I have been trying to render a simple html file with webpack but can't figure out why I'm getting a 404. I understand that bundle.js could not be found so I tried different paths but it didn't work, any ideas?
I would appreciate your help.
Thanks.
app.js
var express = require('express')
var path = require('path')
const app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'html')
app.get('/', function (req, res) {
res.render('index')
})
app.listen(3000, () => console.log('Example app listening on port 3000!'))
webpack.config.js
module.exports = {
entry: ['./src/index.js'],
output: {
path: __dirname,
publicPath: '/',
filename: 'bundle.js'
},
[...]
index.html
<!DOCTYPE html>
<html>
[...]
<body>
<div class="container"></div>
</body>
<script src="./bundle.js"></script>
</html>
Folder structure
You don't have specified a correct path to your index file. If you have it on a src directory the code will look like this:
entry: [
path.resolve(__dirname, 'src/index')
],
[...]
Otherwise if you have it on your views directory, them the code will be the following:
entry: [
path.resolve(__dirname, 'views/index')
],
[...]
And in your html file is <script src="/bundle.js"></script>
UPDATE
Base on your code at github try changing the following lines
entry: [
path.resolve(__dirname, 'src/index')
],
devServer: {
contentBase: path.resolve(__dirname, 'src')
},
output: {
path: __dirname + '/dist', // Note: Physical files are only output by the production build task `npm run build`.
publicPath: '/',
filename: 'bundle.js'
},
The problem consist in that you're missing the path.resolve(...) in both your entry point and your devServer specifically
Hope helps :)
so I have a node/express app that serves back a bundle.js bundled by webpack.
I've been banging my head at this issue for close to 4 nights and I don't know anymore.
I'm getting the Uncaught SyntaxError: Unexpected token < error as the express static middleware is not catching the request and treating it.
webpack.config.js:
output: {
path: BUILD_DIR,
filename: 'bundle.js',
// https://github.com/webpack/webpack-dev-middleware/issues/205
// DO NOT leave publicPath out -- it'll cause errors if we do
publicPath: '/',
},
express middleware:
var serveStatic = require('serve-static')
app.use(serveStatic(
path.join(__dirname, 'statics'),
))
app.use('/dist', express.static('dist'));
app.use('/statics', express.static('statics'));\
index.html:
<script src="bundle.js" type="text/javascript"></script>
I'm trying to set up a very simple script that fetch's data from an API and consumes it's data. I need to use CORS, so I set up a node/express server and pointed it to my Webpack bundle. The error I am getting is global is not defined. From googling this I've seen people fix their problems by disabling react/redux tools which seemed to point at hot reloading. Problem is, I'm not using hot reloading.
After seeing that I looked into what I am using global which pointed at my fetch expression. However, removing all my fetch code didn't solve anything
My server looks like this
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const app = express();
const cors = require('cors');
const port = process.env.PORT || 3000;
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(cors());
app.use(express.static(path.join(__dirname, '../dist')));
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, '../index.html'));
});
app.listen(port, function(){
console.log('server running on http://127.0.0.1:' + port + '/');
});
and my webpack config looks like this
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: ['babel-polyfill', './scripts/app.js'],
target: "node",
output: { path: __dirname, filename: './dist/bundle.js' },
devtool: 'source-map',
module: {
loaders: [
{
test: /.js?$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2015'],
"plugins": ["transform-object-rest-spread"]
}
}
]
}
};
All i can think of now is that I didn't set up my express server correctly or I'm missing something in my webpack config.
Alright, The issue was being caused by placing babel-polyfill in my entry point in my webpack.config. As I already had a preset for ES2015 I didn't need the polyfill.
I am unsure as to why I had placed the babel-polyfill in my entry.
Im trying to get the node-sass-middleware working with with express. The app runs with no errors
...(modules)
var sassMiddleware = require('node-sass-middleware');
var routes = require('./routes/index');
var app = express();
// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
//---- LOAD SASS -----//
// adding the sass middleware
var srcPath = __dirname + '/scss';
var destPath = __dirname + '/public/stylesheets';
app.use(sassMiddleware({
src: srcPath,
dest: destPath,
debug: true,
outputStyle: 'compressed'
}));
app.use(express.static(path.join(__dirname, 'public')));
Can anyone see anything wrong with the way I'm attempting to compile the sass?
file structure :
app
controllers
routes
public
-stylesheets
scss
...
This is how app.js should be:
app.use(sassMiddleware({
src: srcPath,
dest: destPath,
debug: true,
outputStyle: 'compressed'
}),
express.static(path.join(__dirname, 'public')));
Also your main scss file should be named style.scss and be inside scss/stylesheets/ directory.
You should see a log like this, if you have correctly loaded the module:
source : /Users/abc/Desktop/SO/SO_node/scss/stylesheets/style.scss
dest : /Users/abc/Desktop/SO/SO_node/public/stylesheets/stylesheets/style.css
read : /Users/abc/Desktop/SO/SO_node/public/stylesheets/stylesheets/style.css
render : /Users/abc/Desktop/SO/SO_node/scss/stylesheets/style.scss
A problem could also be that you want to compile scss
instead of sass. Therefore set indentedSyntax to false.
app.use(require('node-sass-middleware')({
src: path.join(__dirname, 'scss'),
dest: path.join(__dirname, 'public'),
indentedSyntax : false,
sourceMap: true
}));
Or remove it completly. Express-generator adds this value on default.
Better go for grunt-sass. Simple configuration, automated task (thanks to grunt) and also faster compiling time because of libsass, which is the C version of the original Ruby compiler for SASS. Compile sass/scss files in 0.3 seconds instead of 3.