Angular Cli Webpack, ¿cómo agregar o agrupar archivos js externos?

80

No estoy seguro de cómo incluir archivos JS (proveedores) después de cambiar Angular Cli de SystemJs a Webpack.

Por ejemplo

Opción A

Tengo algunos archivos js que se instalaron a través de npm. Agregar etiquetas de secuencia de comandos a la etiqueta de la cabeza de esta manera no funciona. Tampoco parece la mejor forma.

<head>
   <script src="node_modules/some_package/somejs.js">
</head>

//With systemJs I could do this

<head>
   <script src="vendor/some_package/somejs.js">
</head>

Opción B

Incluya estos archivos js como parte del paquete webpack. Esta parece la forma en que probablemente debería hacerse. Sin embargo, no estoy seguro de cómo hacer esto ya que todo el código del paquete web parece estar oculto detrás del paquete de nodo angular-cli-webpack. Estaba pensando que tal vez hay otra configuración de paquete web a la que podríamos tener acceso. Pero no estoy seguro, ya que no vi ninguno al crear un nuevo proyecto angular-cli-webpack.

Más información:

Los archivos js que estoy tratando de incluir deben incluirse antes del proyecto Angular. Por ejemplo, jQuery y un js lib de terceros que no está realmente configurado para cargar módulos o mecanografiar.

Referencias https://github.com/angular/angular-cli/blob/master/WEBPACK_UPDATE.md https://github.com/angular/angular-cli/tree/webpack

Kris Hollenbeck
fuente
Parece que cambiaron a mecanografiado 2.0
Nathan Smith
Gracias por el enlace, pero eso no es lo que estoy buscando. Eso es para agregar los archivos de definición. Estoy tratando de averiguar cuál es la forma correcta de incluir bibliotecas de JavaScript de terceros en mi proyecto.
Kris Hollenbeck
Ejemplo de webpack angular2 cómo agrupar uno diferente para el proveedor, uno para polimorfismo, uno para la aplicación y otro para css, para mantener la aplicación limpia.
Jorawar Singh

Respuestas:

90

Última prueba usando angular-cli 7.xx con Angular 7.xx

Esto se puede lograr usando scripts:[]en .angular-cli.json.

{
  "project": {
    "version": "1.0.0",
    "name": "my-project"
  },
  "apps": [
    {
      "root": "src",
      "outDir": "dist",
      "assets": ["assets"],
      "index": "index.html",
      "main": "main.ts",
      "polyfills": "polyfills.ts",
      "test": "test.ts",
      "tsconfig": "tsconfig.json",
      "prefix": "app",
      "mobile": false,
      "styles": [
        "styles.css"
      ],
      "scripts": [
        "../node_modules/jquery/dist/jquery.js"
      ],
      "environments": {
        "source": "environments/environment.ts",
        "dev": "environments/environment.ts",
        "prod": "environments/environment.prod.ts"
      }
    }
  ],
  "addons": [],
  "packages": [],
  "e2e": {
    "protractor": {
      "config": "./protractor.conf.js"
    }
  },
  "test": {
    "karma": {
      "config": "./karma.conf.js"
    }
  },
  "defaults": {
    "styleExt": "css",
    "prefixInterfaces": false
  }
}

Nota: Como sugiere la documentación en la instalación de la biblioteca global: si cambia el valor de su propiedad styles( scripts¡ o !), Entonces:

Reinicie ng serve si lo está ejecutando,

..para ver los scripts ejecutados en un ** contexto global a través del scripts.bundle.jsarchivo.

Nota: Como se explica en los comentarios a continuación. Las bibliotecas JS que admiten módulos UMD a través de importaciones de es6 , como jQuery, también se pueden importar a sus archivos de mecanografiado utilizando la sintaxis de importación es6. Por ejemplo: import $ from 'jquery';.

Kris Hollenbeck
fuente
4
¿Cómo puedo hacer referencia a jquery en Typescript una vez que agregué el script a angular-cli.json?
nthaxis
1
Por cierto, si el archivo externo que se agrega es un polyfill, entonces hay un mecanismo dedicado para eso que se describe muy bien en src/polyfills.ts(a partir de la versión beta.31)
rmag
3
Si está utilizando jQuery en su proyecto Angular, lo está haciendo mal. Me encanta jQuery, me llevó lejos en mi carrera, pero si estás usando Angular correctamente, no hay más necesidad de jQuery.
Blair Connolly
5
@BlairConnolly, aunque estoy de acuerdo y nos encantaría deshacernos de jQuery. Estamos consumiendo una interfaz de usuario de Jquery de otro equipo dentro de nuestra empresa que no tiene tiempo para reescribir toda la interfaz de usuario en este momento. Entonces, a veces la gente simplemente no tiene otra opción.
Kris Hollenbeck
1
Hay algo escrito sobre eso aquí que sugiere> Una vez que importe una biblioteca a través de la matriz de scripts, no debe importarla a través de una declaración de importación en su código TypeScript (por ejemplo, importar * como $ desde 'jquery';)
PaulCo
21

Hay una diferencia sutil entre usar y scripts:[]luego agregar algo al <head>con <script>. Los scripts scripts:[]se agregan al scripts.bundle.jsque siempre se cargan en la etiqueta del cuerpo y, por lo tanto, se cargarán DESPUÉS de los scripts en <head>. Así, si el orden es importante carga de la escritura (es decir, tiene que cargar un polyfill global), entonces su única opción es copiar manualmente los scripts en una carpeta (por ejemplo, con un guión NPM) y añadir esta carpeta como un activo a .angular-cli.json.

Entonces, si realmente depende de que algo se cargue antes de angular en sí ( Opción A ), entonces debe copiarlo manualmente a una carpeta que se incluirá en la compilación angular y luego puede cargarlo manualmente con un archivo <script>in <head>.

Por lo tanto, para lograr la opción a , debe:

  • crear una vendorcarpeta ensrc/
  • agregue esta carpeta como un activo a .angular-cli.json:
"assets": [
    "assets",
    "favicon.ico",
     "vendor"
  ]
  • copie su secuencia node_modules/some_package/somejs.jsde comandos de proveedor avendor

  • cargarlo manualmente en index.html: <head> <script src="vendor/some_package/somejs.js"> </head>

Sin embargo, la mayoría de las veces solo necesita este enfoque para los paquetes, que deben estar disponibles globalmente, antes que todo lo demás (es decir, ciertos polyfills). La respuesta de Kris es válida para la Opción B y obtiene el beneficio de la compilación del paquete web (Minificación, Hashes, ...).

Sin embargo, si sus scripts no necesitan estar disponibles globalmente y si están listos para módulos, puede importarlos src/polyfills.tso, mejor aún, importarlos solo cuando los necesite en sus componentes específicos.

Hacer que los scripts estén disponibles globalmente a través scripts:[]o cargándolos manualmente trae su propio conjunto de problemas y realmente solo debe usarse cuando sea absolutamente necesario.

Christian Ulbrich
fuente
Esto es genial porque puedo crear archivos de configuración js por entorno, dejarlos allí y cargarlos en tiempo de ejecución en lugar de usar archivos environment.ts y tener que construir angulares para cada entorno (terrible ...)
Erik Philips
¿Tiene algún ejemplo para usar polyfills o cargar en componentes específicos?
Steve Lam
@SteveLam Por favor sea más específico o haga una nueva pregunta. Por lo general, los polyfills no se cargarían en un componente específico , sino globalmente a menos que desee que sus componentes sean autónomos, pero incluso entonces se prefiere definir el entorno de ejecución que espera y dejar que el consumidor del componente decida cuándo y cómo cargar un polyfill.
Christian Ulbrich
Gracias Chris, ¿tienes algún artículo sobre eso?
Steve Lam
Hola, estoy usando angular 7, cuando ejecuto mi aplicación, el script se carga en la página de índice, pero necesito usar el script en otra página, cuando hago clic en otra página, el script se descarga, ¿cómo puedo cargarlo en una página específica o para una aplicación completa?
luis alberto juarez
3

Debe abrir el .angular-cli.jsonarchivo y buscarlo, "scripts:"o si desea agregar CSS externo, debe encontrar la palabra "styles":en el mismo archivo.

como un ejemplo que se muestra a continuación, verá cómo bootstrap Js ( bootstrap.min.js) y bootstrap CSS ( bootstrap.min.css) se incluyen en .angular-cli.json:

"styles": [
    "styles.css",
    "../node_modules/bootstrap/dist/css/bootstrap.min.css"
  ],
  "scripts": [
    "../node_modules/jquery/dist/jquery.min.js",
    "../node_modules/bootstrap/dist/js/bootstrap.min.js"
  ],

Por supuesto, si tiene su propio archivo js, ​​puede agregar la ruta del archivo aquí en .angular-cli.jsonel mismo lugar (en "scripts":[]).

Prashant Barve
fuente
2

Es posible que desee echar un vistazo a esta página: https://github.com/angular/angular-cli#global-library-installation

Muestra los conceptos básicos de cómo incluir archivos .js y .css

Algunas bibliotecas de JavaScript deben agregarse al alcance global y cargarse como si estuvieran en una etiqueta de script. Podemos hacer esto usando las propiedades apps [0] .scripts y apps [0] .styles de angular-cli.json.

Svenn
fuente
7
No se recomiendan las respuestas de enlace único. Cite las partes esenciales de la respuesta de los enlaces de referencia, ya que la respuesta puede dejar de ser válida si cambian las páginas enlazadas.
Stuart Siegler
-1

No había usado angular-cli antes, pero actualmente estoy trabajando con una compilación Angular / Webpack. Con el fin de ofrecer mi solicitud con jQuery y otros proveedores utilizo el plugin de webpack, ProvidePlugin(). Esto normalmente se ubicará en su webpack.config.js: Aquí hay un ejemplo para las bibliotecas jquery, lodash y moment. Aquí hay un enlace a la documentación (que es vaga en el mejor de los casos)

plugins: [
  new webpack.ProvidePlugin({
    $: 'jquery',
    _: 'lodash',
    moment: 'moment',
  })
]

Increíblemente, en realidad le permite usarlo de inmediato, siempre que todas las demás configuraciones del paquete web se hayan realizado correctamente y se hayan instalado con npm.

zilj
fuente
1
La configuración del paquete web angular cli es en realidad parte del paquete de nodo angular cli. Entonces, lamentablemente, no puedo modificar eso. Por ejemplo, en la CLI hay comandos preestablecidos para construir. ng buildtodo esto es manejado por el cli. Pero estaba pensando que probablemente hay una forma de agregar cosas como parte de la compilación. Pero no he visto ningún ejemplo claro.
Kris Hollenbeck
Ah, mis disculpas. Había filtrado 2 preguntas angulares pero esta se deslizó. La mejor de las suertes.
zilj