¿Cómo administrar las dependencias de JavaScript del lado del cliente? [cerrado]

95

Aunque existen excelentes soluciones para administrar las dependencias en el lado del servidor, no pude encontrar ninguna que satisfaga todas mis necesidades de tener un flujo de trabajo coherente de administración de dependencias de JavaScript en el lado del cliente. Quiero satisfacer estos 5 requisitos:

  1. Administrar mis dependencias del lado del cliente en un formato similar al de la NGP package.json o Bower s'bower.json
  2. Debería tener la flexibilidad de apuntar a git repo o archivos js reales (ya sea en la web o localmente) en mi dependency.jsonarchivo para bibliotecas menos conocidas (npm le permite apuntar a git repos)
  3. Debería minificar y asignar un espacio de nombres a todas las bibliotecas en un solo archivo como ender ; ese es el único archivo js que necesitaría poner en mi <script>etiqueta en el lado del cliente
  4. Debería tener soporte listo para usar para CoffeeScript como BoxJS 4 (ahora muerto)
  5. En el navegador, debería poder usar el estilo require :

    var $ = require('jquery');
    var _ = require('underscore');
    

    O mejor aún, haz el estilo headjs :

    head.js(['jquery', 'underscore', 'mylib'], function($, _, mylib) {
      // executed when all libraries are loaded
    });
    

Si no existe tal herramienta única, ¿cuál es la mejor combinación de herramientas, es decir, una cadena de herramientas que puedo combinar usando algo como volo (o gruñido )?

Ya he investigado todas las herramientas a las que me he vinculado aquí y satisfacen solo hasta 3 de mis requisitos, en el mejor de los casos, individualmente. Por lo tanto, no vuelva a publicar sobre estas herramientas. Solo aceptaría una respuesta que proporcione una única herramienta que satisfaga mis 5 requisitos o si alguien publica un flujo de trabajo / script / ejemplo de trabajo concreto de una cadena de herramientas de múltiples herramientas de este tipo que también satisfaga todos mis requisitos. Gracias.

pathikrit
fuente
6
algo como requirejs.org ?
Chandra Sekhar Walajapet
1
Para una solución más "estilo nodo" que transfiera la requiresintaxis del nodo al navegador, considere browserify
smithclay
1
¿Puedes ser más explícito? De los 5 puntos de mi pregunta, creo que requirejs / browserify solo satisface uno o dos puntos. Estoy buscando una herramienta (o cadena de herramientas) que me permita hacer TODOS mis cinco requisitos
pathikrit
3
No lo probé todavía, pero quizás yeoman.io también sea ​​un buen candidato
Guillaume86
1
Me acabo de enterar de onejs - suena algo relacionado: github.com/azer/onejs
dsummersl

Respuestas:

45

require.js hace todo lo que necesitas.

Mi respuesta a esta pregunta puede ayudarte

Ejemplo:

Jerarquía del proyecto de la aplicación cliente:

sampleapp
    |___ main.js
    |___ cs.js
    |___ require.js

main.js es donde inicializa su aplicación cliente y configura require.js:

require.config({
    baseUrl: "/sampleapp",
    paths: {
        jquery: "libs/jquery", // Local
        underscore: "http://underscorejs.org/underscore-min.js", // Remote
        backbone: "https://github.com/documentcloud/backbone/blob/master/backbone-min.js" // Remote on github
    },
    shim: {
        backbone: {
            deps: ["underscore", "jquery"] // Backbone depends on jquery and underscore
        }
    }
});

require(["cs!someCoffeescriptFile", "jquery", "backbone", "underscore"], function (SomeCoffeescriptFile, $, Backbone, _) {
    // Dependencies are loaded...
    // Execute code
});

Las dependencias usarán el complemento cs cuando estén precedidas por "cs!". El complemento cs compila el archivo coffeescript.

Cuando vas en prod, puede pre-compilar todo el proyecto con r.js .

node ./node_modules/requirejs/bin/r.js -o buildclientconfig.js

Estos son sus requisitos:

  • Administre las dependencias del lado del cliente en un formato similar al package.json de npm o al component.json de bower. ¡Diferente pero TAN BUENO!

  • Debería tener la flexibilidad de apuntar a git repo o archivos js reales (ya sea en la web o localmente) en mi archivo dependency.json para bibliotecas menos conocidas (npm le permite apuntar a git repos). SI

  • Debería minificar y asignar un espacio de nombres a todas las bibliotecas en un solo archivo como ender; ese es el único archivo js que necesitaría poner en mi etiqueta de script en el lado del cliente. con r.js.

  • Debería tener soporte listo para usar para coffeescript como Box. SI

  • En el navegador puedo usar require style o headjs. SI

Jean-Philippe Leclerc
fuente
Si lo uso r.js, ¿puedo simplemente extraer versiones no minificadas de todas las bibliotecas, o cómo debo decidir entre bibliotecas minificadas y no minificadas?
Domi
El único problema es esta basura de requireJS que debes llevar con código minificado.
Ben Sinclair
1
@Andy no necesariamente! ¡Puedes usar Almond en su lugar, que es mucho más pequeño!
Adam B
24

http://requirejs.org/ es el que estás buscando, creo

Chandra Sekhar Walajapet
fuente
gracias por esto. no sabía que esto existe fuera de nodejs
GottZ
1
¡gracias! Si cree que resolvió el propósito, marque mi respuesta como la correcta.
Chandra Sekhar Walajapet
3
No soy yo quien hizo esta pregunta xD
GottZ
¡Ups, lo siento! no me
di
3
Estoy confundido. ¿Cómo exactamente puede requirejs extraer un archivo javascript arbitrario de Internet (no estoy hablando de los que están en su repositorio como jquery sino de los menos famosos)? ¿Puede leer un archivo package.json? Y no funciona con CoffeeScript ... ¿Me estoy perdiendo algo?
pathikrit
15

Como @ Guillaume86, creo que el dobladillo te acercará más a donde quieres estar.

En hem, las dependencias se gestionan mediante una combinación de npm y hem. Utilice npm para instalar explícitamente todas las dependencias externas de sus proyectos. Use hem para especificar qué dependencias (tanto externas como locales) se deben unir para las operaciones del lado del cliente.

Creé un proyecto esqueleto de esto para que pueda ver cómo funcionaría esto; puede verlo en https://github.com/dsummersl/clientsidehem

Agregar dependencias

Use npm para buscar una dependencia específica y luego modifique el archivo package.json para asegurarse de que se realice un seguimiento de la dependencia en el futuro. Luego, especifique la dependencia para su aplicación en slug.json.

Por ejemplo, suponga que desea agregar la dependencia de script de café. Simplemente use npm para instalar la dependencia y guárdelo en su archivo package.json:

1. npm --save install coffee-script
2. Manually edit the slug.json file. Add "coffee-script" to "dependencies".

Suponga que desea incluir su propio módulo 'bloomfilters' y no está en el registro de npm. Puede agregarlo a su proyecto de la siguiente manera:

1. npm --save install https://github.com/dsummersl/bloomfilters/tarball/master
2. Manually edit the slug.json file. Add "bloomfilters" to "dependencies".

Módulos locales

Si desea incluir su propio café o javascript, puede hacerlo agregando esos archivos a la aplicación / carpeta. Tenga en cuenta que para exponer su script a través del método 'require' debe convertirlo en un módulo CommonJS. Es muy simple: consulte los documentos del dobladillo .

Archivos locales

Si desea incluir un código que no sea CommonJS y que no sea 'obligatorio', también puede unirlo haciendo referencia a su JavaScript personalizado o coffeescript a través de la lista 'libs' en slug.json.

CSS

Hem unirá su CSS también, si lo desea. Consulte los documentos de dobladillo .

edificio

Una vez que tenga sus dependencias en la lista, puede usar el dobladillo para unirlas todas.

# make sure all dependencies are present:
npm install .
# make public/application.js
hem build
# see your minified js in public/application.js

Notas

Hem estaba destinado al proyecto spinejs , pero no es necesario que lo uses para eso. Ignore cualquier documento que mencione la columna vertebral como desee ...

dsummersl
fuente
1
+1 por el esfuerzo de entrar en detalles;)
Guillaume86
11

Bueno, me sorprende que nadie haya mencionado todavía Browserify .

  1. admite el formato package.json
  2. usa npm debajo que puede usar un repositorio de github (o cualquier git) como fuente del paquete
  3. minimiza y concatena todas las dependencias en un solo archivo.
  4. admite coffeescript si lo incluye en sus dependencias
  5. requieren estilo en todo momento.
  6. admite mapas de origen
Floby
fuente
¿Puedes usar cualquier repositorio de github (o paquete bower) con browserify? ¿Eso requiere algo como napao no? npmjs.org/package/napa
Connor Leech
9

Estoy bastante seguro de que Hem cumple con sus requisitos (yo uso una bifurcación personal con compiladores adicionales, jade y lápiz, es fácil de personalizar según sus necesidades). Utiliza npm para gestionar las dependencias.

Guillaume86
fuente
De la lectura de esta pregunta en particular, creo que esto resuelve 1,3,5 bastante bien desde el primer momento. Para el n. ° 2, puede poner sus propios paquetes JS locales en node_modules (usa npm local), y puede usar el submódulo git para cualquier dependencia solo en git. Para el n. ° 4, creo que está atrapado en tener que compilar café en js antes de ejecutar hem (lo cual es fácil).
dsummersl
Gracias por el comentario, pero hem compila mi coffeescript sin problemas :), inicialmente se hizo para Spine.js, que es un marco orientado a coffeescript, por lo que es un requisito básico
Guillaume86
Entiendo que lo sería para aplicaciones tipo columna vertebral (es decir, poner café en la aplicación / ...) pero ¿qué pasa con los módulos externos que contienen coffeescript? Creo que eso es lo que pregunta Wick, pero podría estar totalmente equivocado ...
dsummersl
1
Ok, no sé si compila coffeescript para módulos externos, pero no creo que sea útil, los módulos externos generalmente proporcionan el JS compilado :)
Guillaume86
Sí, estoy de acuerdo. Se mete en el ámbito de hacer un cakefile / gruñido ...
dsummersl
5

Es posible que desee echar un vistazo a Yeoman , que utiliza varias técnicas para ayudarlo con sus requisitos.

Nuestro flujo de trabajo se compone de tres herramientas para mejorar su productividad y satisfacción al crear una aplicación web: yo (la herramienta de andamio), grunt (la herramienta de construcción) y bower (para la gestión de paquetes).

Soporte integrado para CoffeeScript, Compass y más. Funciona con r.js ( RequireJS ), unittesting, etc.

En cuanto a sus requisitos:

  1. Bower se utiliza para la gestión de la dependencia
  2. Bower puede trabajar con archivos locales, git: //, http: // y más
  3. Soporte integrado para minificación y concatenación (incluso para sus imágenes)
  4. Soporte integrado para compilar automáticamente CoffeeScript y Compass (con LiveReload)
  5. Como se indica en el proceso de compilación: si está utilizando AMD, pasaré esos módulos a través de r.js para que usted no tenga que hacerlo.

Todas las características:

La velocidad del rayo andamios - nuevos proyectos de andamios fácilmente con plantillas personalizables (por ejemplo para HTML 5, Twitter Bootstrap), RequireJS y más.

Gran proceso de construcción : no solo obtienes minificación y concatenación; También optimizo todos sus archivos de imagen, HTML, compilo sus archivos CoffeeScript y Compass, si está usando AMD, pasaré esos módulos a través de r.js para que usted no tenga que hacerlo.

Compile automáticamente CoffeeScript y Compass : nuestro proceso de vigilancia LiveReload compila automáticamente los archivos de origen y actualiza su navegador cada vez que se realiza un cambio para que usted no tenga que hacerlo.

Limpie automáticamente sus scripts : todos sus scripts se ejecutan automáticamente en JSHint para garantizar que sigan las mejores prácticas del idioma.

Servidor de vista previa incorporado : ya no tendrá que iniciar su propio servidor HTTP. Mi incorporado se puede disparar con un solo comando.

Optimización de imagen impresionante : optimizo todas sus imágenes con OptiPNG y JPEGTran para que sus usuarios puedan dedicar menos tiempo a descargar activos y más tiempo a usar su aplicación.

Gestión de paquetes asesinos : ¿necesita una dependencia? Está a solo una pulsación de tecla. Le permito buscar fácilmente nuevos paquetes a través de la línea de comandos (por ejemplo, `bower search jquery), instalarlos y mantenerlos actualizados sin necesidad de abrir su navegador.

Pruebas unitarias de PhantomJS : ejecute fácilmente sus pruebas unitarias en WebKit sin cabeza a través de PhantomJS. Cuando crea una nueva aplicación, también incluyo algunos andamios de prueba para su aplicación.

MarcoK
fuente
Por favor, deje un comentario para el -1?
MarcoK
4

Bower puede adaptarse a sus necesidades (1) y (2) para el resto que necesite. Desde el archivo Léame:

Bower is a package manager for the web. Bower lets you easily install assets such as images, CSS and JavaScript, and manages dependencies for you.

Para instalar un paquete:

bower install jquery
bower install git://github.com/maccman/package-jquery.git
bower install http://code.jquery.com/jquery-1.7.2.js
bower install ./repos/jquery
user18428
fuente
He investigado todos los que he vinculado en mi OP (incluido Bower) y ninguno de ellos satisface más de 3 de mis 5 requisitos. Estoy buscando una sola herramienta (o una combinación de herramientas) que aborde mis 5 problemas.
Pathikrit
No sé si eso merece un voto negativo, dije que bower + requirejs se adapta a sus necesidades. Dijiste que también estabas abierto a "la mejor combinación de herramientas". Sin embargo
user18428
¿Qué hay de malo en esto: (1) bower (2) también bower (3) requirejs build (4) ya tienes un nodo instalado, no? (5) requirejs
user18428
2

Mira el administrador de paquetes Jam . A continuación se muestra la descripción de su página de inicio.

Para los desarrolladores front-end que anhelan activos mantenibles, Jam es un administrador de paquetes para JavaScript. A diferencia de otros repositorios, primero ponemos el navegador.

Parece muy similar a npm en cómo funciona.

Instale el paquete como a continuación

jam install backbone

mantener los paquetes actualizados ejecutando

jam upgrade
jam upgrade {package} 

Optimice los paquetes para la producción

jam compile compiled.min.js

Las dependencias de jam se pueden agregar en el package.jsonarchivo.

Para obtener la documentación completa, lea la documentación de Jam

himanshu
fuente
2

Me encontré con inject.js

Algunas de las características, desde el sitio del proyecto :

Inject (Apache Software License 2.0) es una forma revolucionaria de administrar sus dependencias de una manera agnóstica de bibliotecas. Algunas de sus características principales incluyen:

  • Cumplimiento de CommonJS en el navegador (exportaciones. *)
  • Ver la matriz de soporte de CommonJS completa
  • Recuperación de archivos entre dominios (a través de easyXDM)
  • localStorage (carga un módulo una vez)
Veverke
fuente
Me gusta inyectar. Es mucho más limpio que RequireJS y casi exactamente como escribir con node.
Mardok
1

Hay un par de opciones:

El componente también puede ser de interés, no administra las dependencias per se, pero le permite usar versiones cortadas de bibliotecas grandes.

JoelKuiper
fuente
1

Utilizo hem con npm y quería agregar algunos beneficios adicionales que creo que no estaban cubiertos hasta ahora.

  • Hem tiene un servidor web autónomo (estratos) para que pueda desarrollar su código sin siquiera tener que volver a compilarlo. Nunca lo uso a hem buildmenos que esté publicando una aplicación.
  • No necesita usar Spine.js para usar hem, puede usarlo para compilar paquetes de coffeescript arbitrarios si configura slug.json correctamente. Aquí está uno de mis paquetes que se compila automáticamente con cakefile: https://github.com/HarvardEconCS/TurkServer/tree/master/turkserver-js-client
  • Hablando de lo anterior, hem le permite vincular otras dependencias en su sistema local con el enlace npm y las combina sin problemas incluso cuando está utilizando el servidor Strata. De hecho, ni siquiera necesita usar el cakemétodo anterior, simplemente puede vincular directamente a coffeescript desde proyectos dependientes.
  • Hem admite eco(Coffeescript incrustado) para vistas y Stylus para CSS, y compila todo eso, junto con su Coffeescript, en un archivo JS y un archivo CSS.

Aquí hay una lista básica para configurar una aplicación Spine, hem, coffeescript. Siéntase libre de ignorar las partes de la columna vertebral. De hecho, a veces utilizo spine apppara configurar una estructura de directorio para una aplicación que no es de Spine, luego edito slug.jsonpara cambiar a una estructura de compilación diferente.

  1. Instale NPM: curl http://npmjs.org/install.sh | shen un sistema * nix. Asumiré que está disponible desde la línea de comandos.
  2. Instale hem globalmente ( npm install -g hem). El desarrollo se ha ramificado últimamente, por lo que es posible que desee obtenerlo directamente de github ( https://github.com/spine/hem ), verificar una rama y npm install -g .en esa carpeta.
  3. npm install -g spine.app hará que spine esté disponible como un comando global
  4. spine app folderhará que la columna vertebral de un proyecto llamado appen folder, la generación de la estructura de directorios de la derecha y un montón de archivos de esqueleto para empezar.
  5. cda la carpeta y edite dependencies.jsonlas bibliotecas que necesite. Agréguelos para slug.jsonque Hem sepa dónde encontrarlos también.
  6. Opcional: npm linkcualquiera de sus paquetes locales en desarrollo para node_modules, y puede agregarlos a slug.jsonpara hem (ya sea index.jspara incluirlo directamente o index.coffeesi desea que hem lo compile).
  7. npm install . para descargar todas las dependencias que acaba de ingresar.
  8. Si echa un vistazo a la configuración predeterminada de la columna vertebral, hay un lugar app/lib/setup.coffeedonde se encuentran requiretodas las bibliotecas que necesita de sus dependencias. Ejemplos:

    # Spine.app had these as dependencies by default
    require('json2ify')
    require('es5-shimify')
    require('jqueryify')
    
    require('spine')
    require('spine/lib/local')
    require('spine/lib/ajax')
    require('spine/lib/manager')
    require('spine/lib/route')
    
    # d3 was installed via dependencies.json
    require 'd3/d3.v2'
  9. En index.coffee, solo tiene que require lib/setupcargar el controlador principal de su aplicación. Además, necesita requirecualquier otra clase en esos otros controladores. Puede utilizar spine controller somethingo spine model somethingpara generar plantillas para controladores y modelos. El controlador Spine típico tiene el siguiente aspecto, utilizando nodos require:

    Spine = require('spine')
    # Require other controllers
    Payment = require('controllers/payment')
    
    class Header extends Spine.Controller
      constructor: ->
        # initialize the class
    
      active: ->
        super
        @render()
    
      render: ->
        # Pull down some eco files
        @html require('views/header')   
    
    # Makes this visible to other controllers    
    module.exports = Header
  10. El generado predeterminado index.htmlgeneralmente estará bien para cargar su aplicación, pero modifíquelo según sea necesario. Según sus requisitos, solo extrae jsun cssarchivo y uno , que nunca necesita modificar.

  11. Edite sus archivos de lápiz según sea necesario en la csscarpeta. Es mucho más flexible que CSS :)
  12. Desde folder, ejecute hem serverpara iniciar un servidor de hem y navegue hasta localhost:9294para ver su aplicación. (Si instaló hem globalmente). Tiene algunos argumentos ocultos, por ejemplo, --host 0.0.0.0escucha en todos los puertos.
  13. Cree el resto de su aplicación utilizando las técnicas MVC adecuadas y use el lápiz óptico para CSS y eco para las vistas. O no use Spine en absoluto, y hem seguirá funcionando muy bien con Coffeescript y npm. Hay muchos ejemplos de proyectos que utilizan ambos modelos.

Una cosa más: normalmente, hem serverse actualizará automáticamente a medida que actualiza su código y guarda archivos, lo que hace que sea muy fácil de depurar. La ejecución hem buildcompilará su aplicación en dos archivos application.js, que está minificado y application.css. Si ejecuta hem serverdespués de esto, usará esos archivos y ya no se actualizará automáticamente. Así que no lo hagas hem buildhasta que realmente necesites una versión reducida de tu aplicación para la implementación.

Referencias adicionales: introducción a Spine.js y hem

Andrew Mao
fuente
1

Aquí hay una solución que adopta un enfoque muy diferente: empaque todos los módulos en un objeto JSON y requiera módulos leyendo y ejecutando el contenido del archivo sin solicitudes adicionales.

Implementación de demostración pura del lado del cliente: http://strd6.github.io/editor/

https://github.com/STRd6/require/blob/master/main.coffee.md

STRd6 / require depende de tener un paquete JSON disponible en tiempo de ejecución. La requirefunción se genera para ese paquete. El paquete contiene todos los archivos que su aplicación podría requerir. No se realizan más solicitudes http porque el paquete agrupa todas las dependencias. Esto es lo más cerca que se puede llegar al estilo Node.js que requiere el cliente.

La estructura del paquete es la siguiente:

entryPoint: "main"
distribution:
  main: 
    content: "alert(\"It worked!\")"
  ...
dependencies:
  <name>: <a package>

A diferencia de Node, un paquete no conoce su nombre externo. Depende del pacakge, incluida la dependencia, nombrarlo. Esto proporciona una encapsulación completa.

Dada toda esa configuración, aquí hay una función que carga un archivo desde dentro de un paquete:

loadModule = (pkg, path) ->
  unless (file = pkg.distribution[path])
    throw "Could not find file at #{path} in #{pkg.name}" 

  program = file.content
  dirname = path.split(fileSeparator)[0...-1].join(fileSeparator)

  module =
    path: dirname
    exports: {}

  context =
    require: generateRequireFn(pkg, module)        
    global: global
    module: module
    exports: module.exports
    PACKAGE: pkg
    __filename: path
    __dirname: dirname

  args = Object.keys(context)
  values = args.map (name) -> context[name]

  Function(args..., program).apply(module, values)

  return module

Este contexto externo proporciona alguna variable a la que tienen acceso los módulos.

Una requirefunción se expone a los módulos, por lo que pueden requerir otros módulos.

También se exponen propiedades adicionales, como una referencia al objeto global y algunos metadatos.

Finalmente ejecutamos el programa dentro del módulo y contexto dado.

Esta respuesta será más útil para aquellos que deseen tener un estilo sincrónico de node.js require una declaración en el navegador y no estén interesados ​​en soluciones de carga de scripts remotos.

Daniel X Moore
fuente
1

Consulte cartero si usa node / express en el backend.

Dave valiente
fuente
0

Le sugiero que consulte el kit de herramientas del dojo que parece cumplir con la mayoría de sus requisitos. El que no estoy seguro es CoffeeScript.

dojo trabaja con módulos escritos en el formato de definición de módulo asincrónico (AMD). Tiene un sistema de compilación con paquetes y puedes agregarlos en uno o varios archivos (llamados capas). Aparentemente acepta repositorios de tipo git, más detalles sobre el sistema de compilación aquí:

http://dojotoolkit.org/documentation/tutorials/1.8/build/

Para el registro, se espera la versión beta v1.9 el próximo mes.

Christophe
fuente
0

Otro marco que satisface todos mis criterios lanzado recientemente: http://duojs.org/ (y también admite el tratamiento de otros recursos como CSS como dependencias).

pathikrit
fuente