node.js - react - coffeescript vs javascript
Herramienta de compilación: proyecto Coffeescript/Node con múltiples componentes (3)
Estoy comenzando un proyecto en el trabajo y me preguntaba cuál sería la mejor herramienta de compilación para usar.
Todo está escrito en CoffeeScript, usando AngularJS para el lado del cliente y NodeJS para el servidor.
Hay varios componentes para la aplicación:
- Una aplicación para iPad
- Una aplicación para iPhone (diferente funcionalidad del iPad)
- Un CMS para las aplicaciones
- Un servidor NodeJS
Hay toneladas de código compartido entre todos estos, nuevamente todo escrito en CoffeeScript.
Me gustaría una herramienta de compilación en la que pueda enumerar qué aplicación usa qué código (gran parte de él compartido) y compilaría los archivos javascript de cada aplicación en una carpeta separada.
Por ejemplo, configuraría una carpeta llamada ''/ compiled / ipad /'' que tiene index.html, y carpetas para js, css, img, etc. Haré una lista de los archivos de café compilados que quiero arrojar en / compiled / ipad / js (parte de /src/shared/*.coffee, parte de /src/ipad/*.coffee, etc.) y qué archivos quiero arrojar en / compiled / ipad / css. Me gustaría que también pueda concatenar fácilmente archivos como yo quiera.
También compilaría mis pruebas, desde / src / test / ipad en / comppiled / test /ipad / * .js.
Todas las pruebas de mi unidad del lado del cliente están escritas utilizando testacular y todavía no estoy seguro de qué escribiré en las pruebas de la unidad del lado del servidor.
¿Qué herramienta / configuración de construcción es el mejor enfoque aquí? Un Makefile? Algo como Grunt? Sinceramente, soy nuevo en toda la escena de construcción.
editar : decidió ir con Browserify. Puede encontrar mi solución para que funcione con Angular aquí: https://groups.google.com/forum/#!topic/angular/ytoVaikOcCs
Hice casi todo esto en un Cakefile usando módulos de nodos según sea necesario.
Establezca algunas variables globales que sean matrices con la ruta de cada archivo, concatenar esos archivos en un archivo en el directorio compilado que especifique, luego compile ese archivo en js.
Para los estilos, lo mismo con la concatenación sin la compilación, obviamente.
fs = require ''fs''
path = require ''path''
{spawn, exec} = require ''child_process''
parser = require(''uglify-js'').parser
uglify = require(''uglify-js'').uglify
cleanCss = require ''clean-css''
coffees =
[
"/src/shared/file1.coffee"
"/src/shared/file2.coffee"
"/src/ipad/file1.coffee"
]
tests =
[
"/src/ipad/tests.coffee"
]
styles =
[
"/src/ipad/styles1.css"
"/src/shared/styles2.css"
]
concatenate = (destinationFile, files, type) ->
newContents = new Array
remaining = files.length
for file, index in files then do (file, index) ->
fs.readFile file, ''utf8'', (err, fileContents) ->
throw err if err
newContents[index] = fileContents
if --remaining is 0
fs.writeFile destinationFile, newContents.join ''/n/n'', ''utf8'', (err) ->
throw err if err
if type is ''styles''
minifyCss fileName
else
compileCoffee fileName
compileCoffee = (file) ->
exec "coffee -c #{file}", (err) ->
throw err if err
# delete coffee file leaving only js
fs.unlink ''path/specifying/compiled_coffee'', (err) ->
throw err if err
minifyJs file
minifyJs = (file) ->
fs.readFile f, ''utf8'', (err, contents) ->
ast = parser.parse contents
ast = uglify.ast_mangle ast
ast = uglify.ast_squeeze ast
minified = uglify.gen_code ast
writeMinified file, minified
writeMinified = (file, contents) ->
fs.writeFile file, contents, ''utf8'', (err) -> throw err if err
minifyCss = (file) ->
fs.readFile file, ''utf8'', (err, contents) ->
throw err if err
minimized = cleanCss.process contents
clean = minimized.replace ''app/assets'', ''''
fs.writeFile file, clean, ''utf8'', (err) ->
throw err if err
task ''compile_coffees'', ''concat, compile, and minify coffees'', ->
concatenate ''/compiled/ipad/code.coffee'', coffees, ''coffee''
task ''concat_styles'', ''concat and minify styles'', ->
concatenate ''/compiled/ipad/css/styles.css'', styles, ''styles''
task ''compile_tests'', ''concat, compile, and minify test'', ->
concatenate ''/compiled/ipad/tests.coffee'', tests, ''tests''
Ahora esto es más o menos lo que creo que estás pidiendo.
Definitivamente podría ser más bonito, especialmente teniendo una función separada para escribir los contenidos minificados, pero funciona.
No era perfecto para los estilos porque estaba usando Sass y tenía otras funciones antes de que tocara la función minimizada, pero creo que ya entendiste la idea.
Personalmente creo que la unidad para escribir el código del lado del servidor en javascript o coffeescript se extiende también a la cadena de herramientas de construcción: así que mantente usando javascript / coffeescript allí también. Esto le permitirá automatizar fácilmente las tareas de su servidor / cliente desde su herramienta de compilación. Dudo que sea significativamente posible con otra herramienta como make (simplemente estaría escribiendo wrappers en las llamadas al comando node.js). Sugerencias ordenadas por estructuración:
- node.js : simplemente despliega tus scripts de compilación en javascript e invocalos con node. Similar a los guiones de shell, supongo. No recomiendo esta ruta.
- Jake o pastel : soy del mundo de Java, por lo que no es sorprendente que estos me recuerden a la hormiga. Prefiero coffeescript, y de ahí prefiero pastel.
- gruñido : no había oído hablar de esto antes, así que no puedo dar muchos consejos. Me recuerda a Maven, por supuesto ... y puedo decir que ... cuanto más estructura tiende a reforzar una herramienta de construcción, menos flexible puede ser. Es algo así como un intercambio. Siempre y cuando lo hagas, la herramienta de construcción te permitirá ahorrar toneladas de tiempo. Pero si tiene problemas específicos de la aplicación, puede ser un dolor real de resolver.
Por supuesto, puede ir con alguna otra herramienta de compilación con la que ya esté familiarizado desde otro idioma: rake, maven, horm, gradle, etc., etc.
Pondría todo el código compartido en los módulos de Node.js y crearía un proyecto que se parecería a lo siguiente:
Project
|~apps/
| |~cms/
| | `-app.js
| |~ipad/
| | `-app.js
| |~iphone/
| | `-app.js
| `~node/
| `-app.js
|~libs/
| |-module.js
| `-module2.js
|~specs/
| |~cms/
| | `-app.js
| |~ipad/
| | `-app.js
| |~iphone/
| | `-app.js
| `~node/
| `-app.js
| `~libs/
| |-module.js
| `-module2.js
`-Makefile
Luego usaría algo como Browserify (hay otros) para hacer las aplicaciones del lado del cliente donde sea necesario. De esa manera, en lugar de tener un archivo de compilación donde digas lo que necesitas, en realidad tienes aplicaciones reales que importan módulos.