NodeJS + CoffeeScript, render coffeescript compiled js on request - node.js

What I would like to do is add the following to me already running coffeescript written server
app.get '/test.js', (req, res) ->
render coffee somecoffeefile.coffee
Is something like this possible with NodeJS, Express, and Coffeescript?
Thanks!
Jose

Good news: This is already comes with Connect (and therefore Express, which extends Connect) as a plugin! It's not well-documented; in fact, I wrote something similar myself (connect-coffee) before I was informed that such a thing already existed.
Here's how you'd go about setting it up with Express:
# Notice the following code is coffescript
# You must add the parens for the app.use method to use in js
coffeeDir = __dirname + '/coffee'
publicDir = __dirname + '/public'
app.use express.compiler(src: coffeeDir, dest: publicDir, enable: ['coffeescript'])
app.use express.static(publicDir)
Now when, say, http://yourapp/foo.js gets requested, if no such file exists in your public directory, foo.coffee will automatically be compiled, and the resulting foo.js will be served. Note that it's important for static to be set up after compiler.
Update: As of Connect 1.7, the compiler middleware has been removed. Partly because of that, and partly to provide a more Rails 3.1-like experience, I've created a new middleware called connect-assets. Install it with npm, then set it up like so:
app.use require('connect-assets')(directory)
where directory is the folder your CoffeeScript files are in (the default is assets). Simple, right? Try it out and let me know what you think.

CoffeeScript = require 'coffee-script'
app.get '/test.js', (req, res) ->
render CoffeeScript.compile coffeeSourceCode

For some reason, the compiler isn't working anymore, so I did this:
fs = require 'fs'
coffee = require 'coffee-script'
app.use express.static "#{__dirname}/static"
app.get '/:script.js', (req, res) ->
res.header 'Content-Type', 'application/x-javascript'
cs = fs.readFileSync "#{__dirname}/coffee/#{req.params.script}.coffee", "ascii"
js = coffee.compile cs
res.send js
Now you can code up coffee/animal.coffee and in your html, do a standard script src='/animal.js'. This hides the implementation detail. The coffeescript is not accessible because "/coffee" dir is not exposed as a static path.
Notes:
This is, of course, a CoffeeScript Node app. I assume if you're using CS for client scripts, you're using it for your server too!
The "static" line is optional. My point is you can happily keep "js" files in the static dir, e.g. library files like jquery.min.js.
Like most Node/Express examples, this is good for development; but for production, you should send cache headers, compress it, and ideally some form of reverse-proxying to avoid reading the file and compiling it each time.

For those of us using the latest version of Connect and Express, I've just published a new module, npm install connect-coffee-script, which compile coffee script files on the fly. Documentation and a sample are provided as well as an introduction article.
Here's an exemple from the readme:
var coffeescript = require('connect-coffee-script');
var connect = require('connect');
var app = connect();
app.use(coffeescript({
src: __dirname,
dest: __dirname + '/public',
bare: true
}));
app.use(connect.static(__dirname + '/public'));
app.listen(3000)

If you would like to use a great existing plugin I would recommend Trevor Burnham's Connect-Assets. It helps compiling, minifying and concatenating .js and .coffee-files and optimizes how the files are being served (a far-future expires header with invalidation using the file's md5-hash). Well written plugin.

coffee-middleware did exactly what I wanted to - minimal setup, no generated files, and not sloppy.
When it gets a request for somescript.js it will check if there is a somescript.coffee. If there is, it will compile it and send it over.
Install it:
npm install coffee-middleware
To use, just add
app.use require('coffee-middleware') src: "#{__dirname}/your/web/root"
before whatever you use to serve static files.
Simple example that serves files in a "public" directory, complies coffeescript before sending it over, and does colored logging:
app = require('express')()
app.use require('morgan') 'dev'
app.use require('coffee-middleware') src: "#{__dirname}/views"
app.use require('serve-static') "#{__dirname}/views"
app.listen 80
To use above code:
mkdir coffeeServer
cd coffeeServer
npm install morgan coffee-middleware serve-static
npm install coffee-script -g
echo 'app = require("express")()
app.use require("morgan") "dev"
app.use require("coffee-middleware") src: "#{__dirname}/views"
app.use require("serve-static") "#{__dirname}/views"
app.listen 80' > server.coffee
coffee -c server.coffee
mkdir views
cd views
echo 'console.log "Hello world!"' > script.coffee
cd ..
node server.js
You can copy the whole bunch into the terminal and it will setup and run the server.
To test:
curl XXX.XXX.XXX.XXX/script.js
That last bit should spit out
(function() {
console.log("Hello world!");
}).call(this);
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NyaXB0LmpzIiwic291cmNlcyI6WyJzY3JpcHQuY29mZmVlIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQUEsRUFBQSxPQUFPLENBQUMsR0FBUixDQUFZLGNBQVosQ0FBQSxDQUFBO0FBQUEifQ==NHS0076
Good luck!

I think you should compile COFFEE files only once, especially with production mode
If you want use coffee with Express 3, or with any web framework look to this repo ExpressOnSteroids You can use this solution, or create your own with Cakefile from this project

You can use Coffee4Clients to render coffee assets to javascript on the fly with your express server.
Update: Coffee4Clients has been killed in favour of DocPad which pre-compiles your assets.

Related

How to properly set Angular for production in NodeJS Express Server?

I have been working for hours on figuring out how to deploy my Angular 6 project on NodeJS Express server,
First, in development i use ng serve which refer to localhost:4200 (default) and another one is Node Express for API (interacting with DB) on localhost:3000. In production i want the Angular build to be served from that Node Express server too.
So what i did was:
Setting up <base href="/"> on index.html on Angular Project
Run ng build --prod it went 100% smooth, no errors.
Copy all files from dist/myprojectname on Angular to Node Express server directory under views/.
In index.js i add following lines app.use(express.static(path.join(__dirname, '/views/')));
it got error something like this
Refused to apply style from 'http://localhost:3001/styles.a64e6aa0f6090e05d2190.css/' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
3localhost/:16 GET http://localhost:3001/runtime.16a329deb1d564eef6599.js/ net::ERR_ABORTED 404 (Not Found)
If i use app.use('/*', express.static(path.join(__dirname, '/views/')));
it will give following error:
Uncaught SyntaxError: Unexpected token <
This seems similar to this issue, are you sure that your css files are NOT starting with comments?
From the linked question's answer:
The issue i think it was with a CSS library starting with comments.
While on dev, i do not minify files and i don't remove comments, this
meant that the stylesheet started with some comments, causing it to be
seen as something different from css.
Hope this helps you this worked perfectly fine for me. The important part of the code is below. My angular application is in ROOT_FOLDER/dist/index.html . You can set the compile/output path in angular.json (variable is outputPath). My express.js file and package.json file is just under the root folder.
const bodyParser = require('body-parser');
const DIST_FOLDER = join(process.cwd(), 'dist');
const STARTING_SERVER_MSG = 'Running server on port %s';
const VIEW_ENGINE_STR = 'view engine';
const HTML_STR = 'html';
const VIEWS_STR = 'views';
const BROWSER_STR = 'browser';
private routes() {
// This part might be useless STRAT_LINK later
this.app.set(VIEW_ENGINE_STR, HTML_STR);
this.app.set(VIEWS_STR, join(DIST_FOLDER));
this.app.use(express.static(join(DIST_FOLDER)));
this.app.use(bodyParser.json());
this.app.use(bodyParser.urlencoded({extended: false}));
// this.app.use('/env', envRouter);
// get router
this.app.use(function (req, res, next) {
res.sendFile(join(DIST_FOLDER, 'index.html'), {req});
});
}

How to configure the page the / path goes to in a tiny express app?

I'm using a simple node express server which is wrapped in the Webpack Dev Server (http://webpack.github.io/docs/webpack-dev-server.html)
I'm starting an express app from a top level directory where the static files are in a directory called "public".
I've got this line of configuration:
server.app.use(express.static(__dirname + '/public'));
If I type http://0.0.0.0:3000/index.html, all is good.
How but the URL of http://0.0.0.0:3000/ produces a directory listing of the top level.
What is the proper way to configure http://0.0.0.0:3000/ to go to the index.html file?
add
server.app.get('/', function(req, res) {
res.sendFile('index.html');
});
See the docs http://devdocs.io/express/index#res.sendFile
The solution involved setting the contentBase proper of the WebpackDevServer plus telling the
server.app.use(express.static(__dirname + contentbase);
Per this diff
The docs are here: http://webpack.github.io/docs/webpack-dev-server.html

NodeJS/Express Workflow with CoffeeScript & Stylus

I have decided to use ExpressJS with CoffeeScript and Stylus. Usually when I work with CoffeeScript, I do a coffee --watch and something similar for Compass/SASS. Here, since CoffeeScript and Stylus are available as a NPM package, I was thinking if its possible to write CoffeeScript and Stylus and have Node/Express compile them when required? This way I wont need a watcher anymore.
Also when I create an express app using express -c stylus, in app.js I get additional:
app.use(require('stylus').middleware({ src: __dirname + '/public' }));
What does it actually do? It doesn't appear to compile my CSS? When I put
body
background: red
into the default style.styl file, restart server, it doesn't appear to show
Ok so theres connect-assets for this exact purpose. Now I am still looking for something for server side ...
try to set
var stylus = require('stylus');
app.use(stylus.middleware({
src: __dirname + '/public',
compile: function(str, path) {
return stylus(str)
.set('filename', path)
.set('compress', false)
.set('warn', true);
}
}));
This compile function is not required, but without it the styl files don't get compiled..

Node.js Railway with sass/stylus/less

i started using railway (a node.js mvc framework) and i want to use sass/less/stylus as a css render engin.
i couldn't find how to configure that in railway.
railway uses express.js so i guess i can install it via that.
i already installed stylus (and all the rest) via npm install stylus.
i also uses stylesheet_link_tag to link to my css files.
any advice will be appreciated.
use https://github.com/emberfeather/less.js-middleware.
its give u what u need
after some research and thanks to my friend #sivan here, i found the answer.
the steps to integrate css rendering engin are (i'll demonstrate with stylus, but the rest are similar):
install stylus
npm install stylus
npmfile.js
require('stylus');
environment.js
var stylus = require('stylus');
app.configure(function(){
var cwd = process.cwd(); //your root directory
app.use(stylus.middleware({
src: __dirname + '/public', //your *.styl files here
compress: true
}));
app.use(express.static(cwd + '/public', {maxAge: 86400000}));
...
}
then create a file ending with .styl extension. for example: public/stylsheets/style1.styl
#div2
color blue //your css here
and simply link to this generated .css file from your html page
<%- stylesheet_link_tag('style1') %>
more about stylus middleware here.
hope it will save time to whoever will get into the same issue.

Express-js can't GET my static files, why?

I've reduced my code to the simplest express-js app I could make:
var express = require("express"),
app = express.createServer();
app.use(express.static(__dirname + '/styles'));
app.listen(3001);
My directory look like this:
static_file.js
/styles
default.css
Yet when I access http://localhost:3001/styles/default.css I get the following error:
Cannot GET / styles /
default.css
I'm using express 2.3.3 and node 0.4.7. What am I doing wrong?
Try http://localhost:3001/default.css.
To have /styles in your request URL, use:
app.use("/styles", express.static(__dirname + '/styles'));
Look at the examples on this page:
//Serve static content for the app from the "public" directory in the application directory.
// GET /style.css etc
app.use(express.static(__dirname + '/public'));
// Mount the middleware at "/static" to serve static content only when their request path is prefixed with "/static".
// GET /static/style.css etc.
app.use('/static', express.static(__dirname + '/public'));
I have the same problem. I have resolved the problem with following code:
app.use('/img',express.static(path.join(__dirname, 'public/images')));
app.use('/js',express.static(path.join(__dirname, 'public/javascripts')));
app.use('/css',express.static(path.join(__dirname, 'public/stylesheets')));
Static request example:
http://pruebaexpress.lite.c9.io/js/socket.io.js
I need a more simple solution. Does it exist?
This work for me:
app.use('*/css',express.static('public/css'));
app.use('*/js',express.static('public/js'));
app.use('*/images',express.static('public/images'));
default.css should be available at http://localhost:3001/default.css
The styles in app.use(express.static(__dirname + '/styles')); just tells express to look in the styles directory for a static file to serve. It doesn't (confusingly) then form part of the path it is available on.
In your server.js :
var express = require("express");
var app = express();
app.use(express.static(__dirname + '/public'));
You have declared express and app separately, create a folder named 'public' or as you like, and yet you can access to these folder. In your template src, you have added the relative path from /public (or the name of your folder destiny to static files). Beware of the bars on the routes.
I am using Bootstrap CSS, JS and Fonts in my application. I created a folder called asset in root directory of the app and place all these folder inside it. Then in server file added following line:
app.use("/asset",express.static("asset"));
This line enables me to load the files that are in the asset directory from the /asset path prefix like: http://localhost:3000/asset/css/bootstrap.min.css.
Now in the views I can simply include CSS and JS like below:
<link href="/asset/css/bootstrap.min.css" rel="stylesheet">
What worked for me is:
Instead of writing app.use(express.static(__dirname + 'public/images')); in your app.js
Simply write
app.use(express.static('public/images'));
i.e remove the root directory name in the path. And then you can use the static path effectively in other js files, For example:
<img src="/images/misc/background.jpg">
Hope this helps :)
to serve static files (css,images,js files)just two steps:
pass the directory of css files to built in middleware express.static
var express = require('express');
var app = express();
/*public is folder in my project directory contains three folders
css,image,js
*/
//css =>folder contains css file
//image=>folder contains images
//js =>folder contains javascript files
app.use(express.static( 'public/css'));
to access css files or images just type in url http://localhost:port/filename.css ex:http://localhost:8081/bootstrap.css
note: to link css files to html just type<link href="file_name.css" rel="stylesheet">
if i write this code
var express = require('express');
var app = express();
app.use('/css',express.static( 'public/css'));
to access the static files just type in url:localhost:port/css/filename.css
ex:http://localhost:8081/css/bootstrap.css
note to link css files with html just add the following line
<link href="css/file_name.css" rel="stylesheet">
this one worked for me
app.use(express.static(path.join(__dirname, 'public')));
app.use('/img',express.static(path.join(__dirname, 'public/images')));
app.use('/shopping-cart/javascripts',express.static(path.join(__dirname, 'public/javascripts')));
app.use('/shopping-cart/stylesheets',express.static(path.join(__dirname, 'public/stylesheets')));
app.use('/user/stylesheets',express.static(path.join(__dirname, 'public/stylesheets')));
app.use('/user/javascripts',express.static(path.join(__dirname, 'public/javascripts')));
Webpack makes things awkward
As a supplement to all the other already existing solutions:
First things first: If you base the paths of your files and directories on the cwd (current working directory), things should work as usual, as the cwd is the folder where you were when you started node (or npm start, yarn run etc).
However...
If you are using webpack, __dirname behavior will be very different, depending on your node.__dirname settings, and your webpack version:
In Webpack v4, the default behavior for __dirname is just /, as documented here.
In this case, you usually want to add this to your config which makes it act like the default in v5, that is __filename and __dirname now behave as-is but for the output file:
module.exports = {
// ...
node: {
// generate actual output file information
// see: https://webpack.js.org/configuration/node/#node__filename
__dirname: false,
__filename: false,
}
};
This has also been discussed here.
In Webpack v5, per the documentation here, the default is already for __filename and __dirname to behave as-is but for the output file, thereby achieving the same result as the config change for v4.
Example
For example, let's say:
you want to add the static public folder
it is located next to your output (usually dist) folder, and you have no sub-folders in dist, it's probably going to look like this
const ServerRoot = path.resolve(__dirname /** dist */, '..');
// ...
app.use(express.static(path.join(ServerRoot, 'public'))
(important: again, this is independent of where your source file is, only looks at where your output files are!)
More advanced Webpack scenarios
Things get more complicated if you have multiple entry points in different output directories, as the __dirname for the same file might be different for output file (that is each file in entry), depending on the location of the output file that this source file was merged into, and what's worse, the same source file might be merged into multiple different output files.
You probably want to avoid this kind of scenario scenario, or, if you cannot avoid it, use Webpack to manage and infuse the correct paths for you, possibly via the DefinePlugin or the EnvironmentPlugin.
The problem with serving __dirname is that __dirname returns the path of the current file, not the project's file.
Also, if you use a dynamic header, each page will look for the static files in a different path and it won't work.
The best, for me, is to substitute __dirname for process.cwd() which ALWAYS donates the path to the project file.
app.use(express.static(process.cwd() + '/public'));
And in your project:
link rel="stylesheet" href="/styles/default.css"
See: What's the difference between process.cwd() vs __dirname?
I was using
app.use(express.static('public'))
When there was no file in the public folder with name index.html.
I was getting the following error in the browser:
"Cannot GET /"
When I renamed the file to 'index.html', it works fine.
Try accessing it with http://localhost:3001/default.css.
app.use(express.static(__dirname + '/styles'));
You are actually giving it the name of folder i.e. styles not your suburl.
I find my css file and add a route to it:
app.get('/css/MyCSS.css', function(req, res){
res.sendFile(__dirname + '/public/css/MyCSS.css');
});
Then it seems to work.
if your setup
myApp
|
|__ public
| |
| |__ stylesheets
| | |
| | |__ style.css
| |
| |___ img
| |
| |__ logo.png
|
|__ app.js
then,
put in app.js
app.use('/static', express.static('public'));
and refer to your style.css: (in some .pug file):
link(rel='stylesheet', href='/static/stylesheets/style.css')
Try './public' instead of __dirname + '/public'.
Similarly, try process.cwd() + '/public'.
Sometimes we lose track of the directories we are working with, its good to avoid assuming that files are located where we are telling express where they are.
Similarly, avoid assuming that in the depths of dependencies the path is being interpreted the same way at every level.
app.use(express.static(__dirname+'/'));
This worked for me, I tried using a public directory but it didn't work.
But in this case, we give access to the whole static files in the directory, hope it helps!
In addition to above, make sure the static file path begins with / (ex... /assets/css)... to serve static files in any directory above the main directory (/main)
Create a folder with 'public' name in Nodejs project
folder.
Put index.html file into of Nodejs project folder.
Put all script and css file into public
folder.
Use app.use( express.static('public'));
and in index.html correct path of scripts to <script type="text/javascript" src="/javasrc/example.js"></script>
And Now all things work fine.
static directory
check the above image(static directory) for dir structure
const publicDirectoryPath = path.join(__dirname,'../public')
app.use(express.static(publicDirectoryPath))
// or
app.use("/", express.static(publicDirectoryPath))
app.use((req, res, next) => {
res.sendFile(path.join(publicDirectoryPath,'index.html'))
In your nodejs file
const express = require('express');
const app = express();
app.use('/static', express.static('path_to_static_folder'));
In your pug file
...
script(type="text/javascript", src="static/your_javascript_filename")
...
Note the "static" word. It must be same in nodejs file and pug file.
i just try this code and working
const exp = require('express');
const app = exp();
app.use(exp.static("public"));
and working,
before (not working) :
const express = require('express');
const app = express();
app.use(express.static("public"));
just try

Resources