What is the best practice to use ExpressJS, VueJS and Jade together?
It's a little bit stupid question, but do I need convert Jade to HTML (like I know, because VueJS can't serve Jade files)?
Do i need serve a Jade or converted HTML index file in ExpressJS?
Without using VueJS, code in my index.js file is something like this:
app.set("view engine", "pug");
app.set("views", __dirname + "/templates");
app.get('/', function(req, res){
res.render("index");
});
And when I want to use Gulp, then.. how?
ExpressJS lives at the back-end and uses your .jade (actually renamed as .pug) templates to generate and serve html. And that's all, next, you can use Vue (client side framework) to develop anything you want.
So, what you can do is, create a .jade template (.pug) like this:
...
body
p {{message}}
script(src='path/to/vue.js')
script.
const app = new Vue({
el: 'body',
data(){
return {
message: 'Hello World!'
}
}
});
It is a simple example. The important thing is that you just are serving a .jade like always, and then, you include the vue library to use it.
Later, you can approach a better front-end development using Gulp and Webpack-Stream tools to compile .vue files.
A gulpfile.js like this, to compile all scripts of your app:
gulp.task('scripts', () => {
return gulp.src("resources/assets/js/main.js")
.pipe(named())
.pipe(webpack(require('./webpack.config')))
.pipe(sourcemaps.init({loadMaps: true}))
.pipe(through.obj(function (file, enc, cb) {
// Dont pipe through any source map files as it will be handled
// by gulp-sourcemaps
var isSourceMap = /\.map$/.test(file.path);
if (!isSourceMap) this.push(file);
cb();
}))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest("./public/js"))
.pipe(notify("Scripts compiled"));
});
The content of your webpack.config.js could be:
module.exports = {
devtool: 'source-map',
module: {
loaders: [
{ test: /\.vue/, loader: 'vue' },
],
},
};
*Note that you will need the vue-loader package to let Webpack compile .vue files
By this way you will be able to develop a complete Express & Jade + VueJS application.
I hope it helps.
You need to compile jade file into HTML. I used prepros for compiling. But I already transfer to haml instead of jade. But this will work perfectly.
for inline javascript. Use this
script.
if(usingJade)
console.log('you are awesome')
else
console.log('you are not awesome');
In general case - using of webpack is already enough for goal.
I have similar case before with entry jade template and .vue files. Based on this example
Related
I have a task for pug in a gulpfile.js that is something like this:
gulp.task('pug', function () {
return gulp.src('bundle/pages/**/*.pug')
.pipe(pug({
pretty:true,
globals: ???,
e.t.c.????????????????????
}))
.pipe(gulp.dest('bundle/pages/'))
})
In pug docs we can see many options, but usually people use only "pretty:true". In docs I saw some interesting options like "globals" e.t.c
I want to include a global mixins file to all pug files without writing this inclusion in every .pug file like: "include ../../blah-blah/blah/global-mixins.pug:" at the top.
Is it possible to connect global-mixins.pug or another pug file using a pug pipe in gulpfile.js or not???
And where i can see an example of using all of the pug options in gulpfile.js, not just "pretty:true"???
https://pugjs.org/api/reference.html
Im getting started with webpack but one thing I cannot for the life of me work out is how to take a folder (with possible nested folders), full of .pug templates, and simply compile them to static html and put them in the output folder, maintaining any nested folder structure for each output html file that was in the source templates folder...
I dont want to have to manually specify each individual .pug file, and I definitely dont want webpack to try and parse the .pugs into JS and then attempt to require/import any of the imgs/fonts etc in the pug files and then complain about it, Im just after a basic, static 1:1 compile, pug file in, html file out. Why is it so hard to do that?
Use pug-html-loader to convert .pug to .html file. Use file-loader to copy the file to desired location. Don't use html-loader as you don't want to process resources used by the generated file.
You will end up something like this in your loader rules (untested, webpack 1 syntax, you may need to tweak it for webpack 2)
{
test: /\.pug$/,
loaders: ['file-loader?name=[path][name].html', 'pug-html-loader?pretty&exports=false']
}
Next you need to require all your pug files in your entry file
function requireAll (r) { r.keys().forEach(r); }
requireAll(require.context('./', true, /\.pug$/));
This can be done very simply with only html-webpack-plugin and pug-loader.
webpack.config.js
const HTMLWebpackPlugin = require('html-webpack-plugin');
module.exports = {
// No javascript entrypoint to evaluate. Let the plugin do the heavy lifting
entry: {},
// Translate Pug to HTML
module: { rules: [ { test: /\.pug$/, use: 'pug-loader' } ] },
// Save HTML to file
plugins: [ new HTMLWebpackPlugin({ template: './src/index.pug' }) ]
};
./src/index.pug
doctype html
html(land="en")
head
include path/to/another.pug
...
Got this information from https://extri.co/2017/05/23/using-htmlwebpackplugin-and-pug/ and you can also go further to import css and javascript as normally done with html-webpack-plugin.
I am minifying an index.html file with gulp (note: took over this project, build system has been done by former dev).
It all works fine, but the gulp task generates a HTML file which has a cryptic extension to it, like:
index-bd2c7f58f0.html
I understand this must have it's advantage, but I can't grasp what...:) Because the disadvantage now is:
The node server needs the presence of an index.html file to allow the '/' route to work.
Thus so far, I either have to copy the file on every build or create a link which needs to be updated on every build
What am I missing? Should I just instruct gulp to create a plain index.html file, or what are best practices here?
Also, which of the various plugin calls is actually responsible for attaching that extension to the file name?
EDIT: Seems to be the gulp-rev and revReplace calls
Here is the gulp task I am using:
gulp.task('html', ['styles', 'scripts'], function () {
var client = buildHTML('./client/index.html', './dist/public');
return merge(client);
});
function buildHTML(index, distFolder) {
var lazypipe = require('lazypipe');
var saveHTML = lazypipe()
.pipe($.htmlmin, {
removeComments: true,
removeOptionalTags: true
})
.pipe(gulp.dest, distFolder);
return gulp.src(index)
.pipe($.useref())
.pipe($.rev())
.pipe($.revReplace({replaceInExtensions: ['.js', '.css', '.html', '.ejs']}))
.pipe($.if('*.html', saveHTML()));
}
One advantage that I'm familiar with is when it's used with assets, when you recompile the asset and create a new fingerprint for that file, the request won't return the cached response because it's a different file. As for your problem, you probably shouldn't be adding that has to your index, I think it's pretty unorthodox
I have a directory app/server/views/ wherein all the jade files are present. As my application is now beginning to have more jade files, I thought of structuring app/server/views/ based on category of actors for simplicity & maintainence. Something like:
app/server/views/admin/task1.jade
app/server/views/admin/task2.jade
app/server/views/superadmin/task1.jade
app/server/views/superadmin/task2.jade
app/server/views/user/task1.jade
app/server/views/user/task2.jade
If all the jade files are present inside /app/server/views/ directory, my index.js file has no problem in loading the jade files. However on structuring per above mentioned directory format, I run into issues:
server.views({
engines:
{
jade: require('jade')
},
path: [ __dirname + "/app/server/views/admin", __dirname + "/app/server/views/superadmin", __dirname + "/app/server/views/user" ]
});
With the above index file, my jade files won't load.
I don't think path can be an array. From the docs, I gather that it should be one directory.
Something like path: Path.join( __dirname, 'app/server/views' ) then call the templates from your controller as reply( 'admin/task1', ....).
If you can determine your actor's role programatically and have exactly the same code, then something like reply( actorsRole + '/task1' ) should do the trick.
I have express application in nodejs:
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
My js files which go the browser are in /public folder. I want to obfuscate them automatically in runtime, so it'd be hard to read them in the browser. Is it possible to tune this app setup somehow?
Don't obfuscate at runtime. Create a build step which obfuscates your code and serve the obfuscated code in production.
Install UglifyJS:
npm install -g uglify-js
Then you can run the following command to obfuscate your code:
uglifyjs < src/script.js > dist/script.js
Alternatively, install grunt and the uglify plugin:
npm install -g grunt-cli
npm install --save-dev grunt grunt-contrib-uglify
Create a file called "Gruntfile" in the root of your project with the following contents:
'use strict';
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.initConfig({
uglify: {
all: {
files: {
'public/scripts.js': 'src/**/*.js'
}
}
}
});
grunt.registerTask('default', ['uglify']);
};
Run grunt from anywhere in your project to obfuscate your code. Update the index.html file in public/ with a <script src="scripts.js"></script> to load the obfuscated, concatenated scripts.
If order matters, list your scripts in order:
files: {
'public/scripts.js': [
'src/1.js',
'src/3.js',
'src/2.js'
]
}
So, you can't actually keep a user from reading your javascript when it's sent to the browser. You can make it very hard, but a determined user will always be able to transform it to something readable through a combination of automated tools and manual labor.
In short, there's no DRM for JavaScript (or any code, for that matter). If you want to protect the intellectual property in your scripts, put a copyright notice on them. If you think someone stole them, talk to a lawyer.
It's certainly worthwhile to minify your JavaScripts, but the only reason, in my opinion, to obfuscate them is because your stupid boss told you to.
If you want to obfuscate it, check out the answer to this question:
How can I obfuscate (protect) JavaScript?
Note that obfuscation is rather expensive, so you really don't want to do it at runtime. You should simply apply it to your javascripts when they change using a build tool like grunt or bower (personally I prefer grunt). These systems have plugins like this to perform the obfuscation.
You can use UglifyJs in your node application and do what you need using its API. Check out their documentation for further details.
Example from Unglify docs
var jsp = require("uglify-js").parser;
var pro = require("uglify-js").uglify;
var orig_code = "... JS code here";
var ast = jsp.parse(orig_code); // parse code and get the initial AST
ast = pro.ast_mangle(ast); // get a new AST with mangled names
ast = pro.ast_squeeze(ast); // get an AST with compression optimizations
var final_code = pro.gen_code(ast); // compressed code here
P.S. People noting that it is slow and blah blah are of course all correct, but hey, if you need it here it is, I just don't understand why judge and post opinions in response to a clear question.
You can obfuscate the code using command line utility, such as this:
app.use('/javascripts',function(req,res,next){
if (process.env.OBFUSCATE != 1){
next();
}
var cmd = "java -jar ./gcc/compiler.jar ./public/javascripts" + req.url;// + "> ./tmp" + req.url + ".tmp";
exec(cmd,function (error, stdout, stderr){
res.write(stdout);
res.end();
if(error !== null){
console.log('exec error: ' + error);
}
});
});
My tips are easily bypassed, but without be careful, we can be trapped. And it is only client part, not nodejs part.
Only live view of the page
You can replace or remove script tag with javascript for hide this in live view of the page. But if you watch directly the network, you can see easily the javascript file/code.
<div id="RemoveMe0">
<script type="text/javascript">
//This code it is hidden to live view.
var my_var = 5 + 5;
$('#RemoveMe0').remove();
//or document.getElementById("RemoveMe0").innerHTML = "";
</script>
</div>
For include javascript :
<div id="RemoveMe1">
<script type="text/javascript" src="Javascript/MyJS.js"></script>
<script>
//Your include it is hidden to live view.
$('#RemoveMe1').remove();
</script>
</div>
Only direct view
Put your files in an HTML file (myfile.js to myfile.html), like this on a direct view you can execute a javascript function.
function Hello() {
alert("Hello");
}
Hello();
//<script>document.body.innerHTML = "";</script>
Conclusion :
For this tip, rename file or use .htaccess. And like first tip, if you watching the network you see full file.
Or minize/parse your JS
You can use tool like this :
minize your js : This tool use eval function, and try to complicate your script.
Javascript Obfuscator : Complicates the code for beginners, it's easy to by-pass.
Google Closure JS Compiler : Optimize, compress, and minify your code. It is a natural tool for the production environment.
I see you are using express and EJS. What I do is create another folder called jsobf that holds the obfucated files. Basically duplicate all your js files with the same name if you want.
In EJS you can do if else check in your ejs files like this :
<% if (process.env.NODE_ENV === "production") { %>
<script src="/jsobf/myjavascriptfile-prod.js"></script>
<% } else { %>
<script src="/js/myjavascriptfile-dev.js"></script>
<% } %>
At the top of the file where you do app.listen.. declare you a global variable:
const isProduction = true;
app.listen(PORT, function () {
if(isProduction){
process.env.NODE_ENV = 'production';
}
});
Then all you need to do before you deploy your code is manually obfuscate your code at a site like obfuscator.io
In your dev branch set the isProduction to false and in production branch to true. This way when you are developing everything is taken care of for you.
This may not be the cleanest solution but it works perfectly fine for me if you dont care to obfuscate manually before production deploys.