Express: how to generate browser specific css at app startup once and serve it - node.js

Problem: I don't want to send prefixfree.js to client each time, i think it may not be good for speed and can be solved at server side.
But at the same time i don't want server to redo the same work over and over again. I want serer to do this:
when server is started...
Convert less to css
make 4 versions of all css files:
webkit
moz
ie
all browsers
then serve them appropriately, so if browser agent is webkit, serve webkit version of that css file. and if can't be determined then serve the all version.
Now i could serve the all file instead, and i know it won't add that much to the size of file. But i don't know how to make less compiler output a prefixed version and i don't want to go each css file in command line and run some command to add prefixes. Also, isn't a good practice to try to improve the flow as much as possible.
I could also use some ide plugin to add prefixes in less file, but that makes css files huge and hard to debug.

To make the right decision you should find out which browsers you have to support. Yous should also consider Graceful degradation.
Personal i think running Less with the autoprefix and clean-css is a safe choice in most situations.
Testing is simple:
npm install less
npm install less-plugin-clean-css
npm install less-plugin-autoprefix
lessc source.less production.css --autoprefix --clean-css
Notice that you can set your target browsers as an argument for the autoprefix plugin. To support the same browsers as Bootstrap does use the following:
--autoprefix='Android 2.3','Android >= 4','Chrome >= 20','Firefox >= 24','iOS >= 6','Opera >= 12','Safari >= 6'
You are right. Vendor prefixes will make your CSS file larger. You should notice you can compress / minify your code (also zip) and you code can be cached by the browser.
You should compare the larger code with -prefix-fee; 2kb gziped an extra http process and some JavaScript processing. Vera explains why using it can be a good idea at: http://css-tricks.com/five-questions-with-lea-verou/
You idea is somewhere between the above two solutions. You css code is possible a little smaller, but you still will need some JavaScript processing to find out the browser of the user.
I could also use some ide plugin to add prefixes in less file, but that > makes css files huge and hard to debug.
You can use the autoprefix plugin together with CSS sourcemap for easy debugging (use the --source-map option of the Less compiler). In most situations you will have a develop and production version of your code.
As already made clear by #seven-phases-max you can integrate all the above in a build chain with Grunt or Gulp.

Related

How can I make vscode assume a node.js context, so that it doesn't assume `fetch` exists?

By default, when editing a JavaScript file in VSCode, it will assume that the fetch function and related types exist in the current context. This makes sense for JavaScript designed to run in the browser, but when running on node.js the fetch function does not exist unless it is installed via node-fetch. I find that in this context, VSCode is misleading, as it will not highlight an error when you trying calling the fetch function, or access other types such as Request and Response, even though they do not exist unless you have node-fetch installed.
How can I configure vscode to assume a node.js context, and therefore assume that fetch does not exist unless I explicitly import it from node-fetch?
Why web types are there by default
From the docs for tsconfig.json compilerOptions.lib:
TypeScript includes a default set of type definitions for built-in JS APIs (like Math), as well as type definitions for things found in browser environments (like document).
How to change the defaults
Create a tsconfig.json or jsconfig.json, and set the compilerOptions.lib array to not contain "DOM", which means that lib.dom.d.ts (the "DOM standard library" type definitions file that comes with TypeScript) will not be assumed. You should specify which ECMA Script standard you want to write your source code in.
The config file also has fields to control what files it takes effect on: files, include, and exclude. If you specify none of them, include will default to **, which matches everything beside and recursively under subdirectories beside the config file.
Having to create this file could be seen as annoying if you just want to write a single JS file (ie. now you have a whole config file just for one source file!). I don't know if there are alternatives that are more convenient for such a use case. If anyone knows, please edit this answer.
I looked briefly into TypeScript triple-slash directives, which allow specifying things on a per-file basis, but I think you can only add things (ie. I don't think you can use them to remove a lib).
At the time of this writing, there are VS Code settings that can be applied at the user-settings scope that affect settings for implicit projects (JS/TS files which don't have a project config file) (js/ts.implicitProjectConfig.*), but none of them are for setting the compileOptions.lib field, and my gut says it's probably not going to happen (but don't quote me on that).
You probably also want types for the Node API
Use npm to install a version of #types/node. Make sure the major version number of the version you install matches the major version number of the version of Node JS you want to script to be runnable on.
Fun irrelevant facts to this question
Continuing on the point about VS Code's user-settings for implicit projects, VS Code puts some defaults in effect (on top of those that TypeScript itself does) if no project is detected. You can poke through the code at github.dev/microsoft/vscode by doing "Find in Files", using extensions/typescript-language-features/**/* as the "files to include" field, and compilerOptions as the find query. compilerOptions.lib seems to not be something that VS Code touches in such a scenario.

In typescript, how to restrict a typing reference to a certain file?

I'm trying to cleanly write some universal javascript code, for node and browser.
Most of the code is env-agnostic, however, some implementation parts detect the environment (node or browser) and conditionally execute different code.
I would like to activate node typings ONLY for those specific files. However, I couldn't find a way to do so. Either:
node typings, when referenced in even one file only, are made effective for all files (bad, since I could inadvertently rely on node specificities)
if not referencing node typings at all, typescript obviously complains about a lot of unknown definitions, which would be painful to patch by hand
Do anyone has a clean way of activating some type definitions for a selected set of files ?
It's not possible at this time.
A solution: building node-dependant and node-independant files separately. This could be done automatically with a script.

Debug concat/minified files with Grunt

I'm using grunt concat/uglify to reduce the number of calls being made to load JavaScript.
I removed all the hard-coded links to the actual javascript files, and now reference the one javascript file produced by grunt.
how can I continue to debug/view my javascript in my development environment?
Is that what source maps are?
i.e.
https://www.npmjs.org/package/grunt-concat-sourcemap
Yes. You will need to generate a sourcemap to continue debugging your code easily.
There are two types of sourcemap, but the sourcemaps need to be maintained through each transition. SO if you concat in one step an minify in a second step, the minify process needs to know that the concat step generated a sourcemap and generate it's own sourcemap based on that sourcemap, so that the minified code sourcemap corresponds to the original input, not the input from the concat step.
There are several ways around this -- the easiest way is to just not minify in your test/deveopment environment. There are also minifiers that will do the sourcemapping correctly for you, but they can be hard to configure.
You might also want to take a look at browserify -- this is a tool that lets you write your front-end browser code like it was node modules, and it will concat and generate sourcemaps for you!
Alternatively you can also just rely on gzip compression from your server and run your code through a minifier -- this works surprisingly well.

How use dev and prod assets in NodeJS/Express/Jade properly

I have a NodeJS application with Express based structure and Jade module for a views. I need to use a full version my assets on a developer machine and min version in production machine.
Can you explain best practices of how should I do it properly?
EDIT: If you put a minus please describe the reason.
Not sure why there isn't an "official" way of doing this (compared to what Ruby on Rails does).
Here are a few suggestions:
DIY
Here's what I've been doing so far:
At server startup, I run uglify-js on all the js files (under .../js, and create the minified version under .../min) with something like so (leaving out the reading/writing of the files):
var jsp = require('uglify-js').parser;
var pro = require('uglify-js').uglify;
var ast = jsp.parse(code.toString('utf8')); // 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
then in html templates, based on some environment variable to trigger production environment, I generate the path for the <script> tags to either point to .../js or .../min.
This leaves out quite a lot (where you would group all js files into one minimized one to reduce the number of browser queries and such), but hopefully this can help you craft your own strategy.
Piler
That said, I've been meaning to try piler (https://github.com/epeli/piler), which seems to be a better alternative to the DYI way.
Using Grunt
Grunt.js (http://gruntjs.com/) is also quite suitable to help preprocess files (html, js, css, ...)
Here are a few pointers:
grunt-recess: https://github.com/sindresorhus/grunt-recess (especially interesting if you use less)
how to config grunt.js to minify files separately
Grunt tasks to process HTML files and produce a deploy directory of optimized files (https://gist.github.com/necolas/3024891)
I view minification as a build step and prefer to not burden the application at runtime with it. Therefore, I would setup my HTML files to refer to file paths which are generated from the build tool and then use the build tool to figure out whether or not to minify.
I haven't actually needed to make it conditional myself because I haven't needed to have unminified code in the browser. With grunt setup to watch the source files and recompile automatically, I can edit a JavaScript source file and it automatically gets rebuilt and placed into the appropriate runtime location. However, I could see this being useful for stepping through code. IE 9 has a formatter in its dev console which is useful for debugging minified code, but I'm not sure how common that is across browsers.
If I were to skip minification in development, I would first check if I can make the grunt uglify task use a config setting like an environment variable or npm setting, etc. to decide whether to actually uglify or not. If that is not possible, I would make a separate grunt task called "devBuild" that does everything except uglify.

how to distribute a Flash component for use with MTASC?

I have a Flash component that's just a library of compiled code with some exposed API calls. Normally we distribute this as a SWC or MXP, and it works just fine. Recently I had a client express interest in using my component, but they do all their development in MTASC only. MTASC doesn't support SWC files, so ss there a good way to send precompiled code that would work in MTASC? I'm not able to send them the original source code, but if there's some other method I'd appreciate it. I do have access to the source, so I can recompile it however necessary. Thanks!
I did find an answer, and I'm not 100% sure if this is exactly the process since I'm no longer at that job and don't have the computer/process in front of me anymore. It was a bit of a hack.
What it involved basically was unzipping the SWC file and getting a .swf and a bunch of .asi files out.
The .asi files are really just ActionScript files, but they contain intrinsic definitions, or just prototypes or footprints of whats actually there. The real meat of it is still in the .swf.
So you rename all those .asi files to .as and then put them into your MTASC classpath. Since they contain definitions, you shouldn't be getting any more "undefined variable" or "undefined function" errors at compile time. Now you just need to pull in the SWF, where the actual function bodies are defined, using loadMovie. once the loadMovie is complete, you should be able to use all of the functions.
The only caveat of course is that you have to wait for that SWF to load before calling of any of the functions from the SWC.
so step-by-step, it looks like this:
1.) unzip the SWC file. this can be done using WinZip or OS X terminal unzip command
2.) Rename .asi files to .as
3.) add new .as files to MTASC classpath
4.) add AS code to load the .swf in and make sure none of the SWC functions are called before the SWF is loaded
5.) compile
I'm pretty sure this is what we did, but i'm not in a spot to try it out right now.,
Hope this helps, let me know if you have any other questions and I'll see if I can help figure it out any more.

Resources