Escribir componentes reutilizables en ES6

 

 

 

  • Clase magistral de diseño para una interfaz de usuario compleja, con Vitaly Friedman
  • Design Token and UI Component Architecture, with Nathan Curtis

  • Índice
    1. Las herramientas
    2. La meta
      1. Escribir en ES6, usar en ES5
      2. Facilite el consumo para cualquiera
    3. Configurando nuestro proyecto
    4. La clase de personaje de Lego
    5. El index.js
    6. DE ACUERDO. ¿Ahora que?
    7. Ingrese al paquete web
      1. Cargadores
    8. Producción
    9. Exterioridad
    10. El cargador de Babel
    11. ¿Qué pasó exactamente?
    12. ¡Es utilizable!
    13. Moviéndose a tragar
      1. Configurar una tarea de compilación
      2. ¿Qué pasa con la minificación?
    14. Complemento de banner de paquete web
    15. ¿Que sigue?
      1. Otras lecturas

    Ha habido algunos avances cuánticos sorprendentes en las herramientas de JavaScript que le han permitido sumergirse de lleno en la escritura de módulos ES6 completos, sin comprometer los elementos esenciales como las pruebas, el linting y (lo más importante) la capacidad de que otros consuman fácilmente lo que nosotros. escribir. En este artículo, Jim Cowart se centrará en cómo crear un paquete JavaScript escrito en ES6 que se pueda utilizar en un sitio o aplicación independientemente de si está utilizando CommonJS, definición de módulo asincrónico (AMD) o módulos globales de navegador simple.

     

    ¿Está entusiasmado por aprovechar las nuevas funciones del lenguaje JavaScript pero no está seguro de por dónde empezar ni cómo ? ¡No estás solo! Pasé la mayor parte del último año y medio tratando de aliviar este dolor. Durante ese tiempo se han producido algunos avances cuánticos sorprendentes en las herramientas de JavaScript.

    Estos avances nos han permitido a usted y a mí sumergirnos de lleno en la escritura de módulos ES6 completos, sin comprometer los elementos esenciales como las pruebas, el linting y (lo más importante) la capacidad de que otros consuman fácilmente lo que escribimos.

    En esta publicación, nos centraremos en cómo crear un paquete JavaScript escrito en ES6 que se pueda utilizar en un sitio o aplicación independientemente de si está utilizando CommonJS, definición de módulo asincrónico (AMD) o módulos globales de navegador simple.

    "Espera, ¿es ES6 o ES2015? Mis hábitos ciertamente prefieren ES6, pero el nombre se cambió recientemente y oficialmente a ES2015. Sin embargo, hay un mayor nivel de conocimiento de ES6, que es como me referiré a él en esta publicación.

    También me gustaría agradecer especialmente a Doug Neiner y Ryan Niemeyer ; ambos han compartido este viaje hacia mejores herramientas ES6. Este post no habría sido posible sin ellos."

    Las herramientas

    En las partes 1 y 2 de esta serie, veremos algunas de las herramientas que lo hacen posible. Hoy cubriremos la escritura, transpilación y empaquetado de nuestra biblioteca; y en la parte 2 nos centraremos en linting, formateo y pruebas (usando JSCS, ESLint, mocha, Chai, Karma y Estambul). Conoce a tus nuevos mejores amigos para la parte 1:

    • Babel (que acaba de celebrar su primer cumpleaños) ha hecho que el proceso de transpilación de ES6 a ES5 no sólo sea sencillo, sino también agradable .
    • webpack silenció todos los aspectos de las "guerras de módulos" en mi equipo al permitirnos consumir todo (CommonJS, AMD y ES6) con aplomo. Resulta que webpack también hace un trabajo fantástico al empaquetar bibliotecas ES6 independientes, un hecho que analizaremos de cerca durante esta publicación.
    • Gulp es una herramienta poderosa para automatizar tareas relacionadas con la compilación.

    La meta

    Escribir en ES6, usar en ES5

    Hablaremos de escribir bibliotecas del lado del cliente de ES6 , no de agrupar sitios o aplicaciones completos. (En realidad, se trata de cualquier fragmento de código reutilizable que le gustaría compartir entre proyectos, ya sea un proyecto de software de código abierto o algo que utilice internamente en el trabajo entre aplicaciones). “Espera un segundo” , podrías estar pensando. "¿No pasará un tiempo hasta que el rango de navegadores que debo soportar pueda manejar ES6?"

     

    ¡Eso es correcto! Sin embargo, mencioné Babel anteriormente porque lo usaremos para convertir nuestro ES6 a ES5, lo que lo convierte en una opción práctica para usar hoy en día en la mayoría de las situaciones.

    ¿Qué hay de nuevo en ES6?

    ES6 es la próxima gran versión de JavaScript y tiene algunas características nuevas excelentes. Las funciones tienen distintos grados de complejidad y son útiles tanto en scripts simples como en aplicaciones complejas. Cubramos una selección cuidadosamente seleccionada de características de ES6 que puede usar en su codificación JavaScript diaria, ¿de acuerdo?Leer un artículo relacionado →

    Facilite el consumo para cualquiera

    La segunda parte de nuestro objetivo es escribir un módulo que podamos usar en los ecosistemas de módulos más comunes. ¿Fanático acérrimo de AMD? Obtienes un módulo. ¿CommonJS plus busca la única canción que cantas? Y obtienes un módulo. ¿No estás seguro de a qué se debe el alboroto entre AMD y CommonJS y simplemente quieres colocar la scriptetiqueta en la página y listo? ¡También obtienes un módulo! Es un poco como un sorteo de un módulo de Oprah, donde el papel de Oprah lo desempeña webpack . webpack ayudará a empaquetar nuestro módulo en un contenedor especial llamado definición de módulo universal (UMD) , lo que permitirá consumirlo en cualquiera de los escenarios anteriores.

    Configurando nuestro proyecto

    Durante los próximos minutos, trabajaremos en el código resultante aquí . Normalmente comienzo un proyecto con las carpetas src/ , spec/ y lib/ . En nuestra carpeta src/ , verá un conjunto ideado pero divertido de módulos de ejemplo que, cuando se usan juntos, nos permiten recuperar una cita aleatoria de un personaje de la película Lego . Si bien el comportamiento es bastante inútil, este ejemplo utiliza clases , módulos , desestructuraciónconst , un generador y más: todas características que nos gustaría transpilar de forma segura a ES5.

    El objetivo principal de esta publicación es discutir cómo usar Babel y webpack para transpilar y empaquetar una biblioteca ES6. Sin embargo, también quería echar un vistazo breve a nuestro código de ejemplo para que pueda ver que efectivamente estamos usando ES6.

    Nota: No se preocupe si es nuevo en la sintaxis de ES6. Estos ejemplos son bastante simples de seguir.

    La clase de personaje de Lego

    En nuestro módulo LegoCharacter.js , vemos lo siguiente (asegúrese de leer los comentarios para obtener más explicaciones):

    // LegoCharacter.js// Let's import only the getRandom method from utils.jsimport { getRandom } from "./utils";// the LegoCharacter class is the default export of the module, similar// in concept to how many node module authors would export a single valueexport default class LegoCharacter { // We use destructuring to match properties on the object // passed into separate variables for character and actor constructor( { character, actor } ) { this.actor = actor; this.name = character; this.sayings = [ "I haven't been given any funny quotes yet." ]; } // shorthand method syntax, FOR THE WIN // I've been making this typo for years, it's finally valid syntax :) saySomething() { return this.sayings[ getRandom( 0, this.sayings.length - 1 ) ]; }}

    Bastante aburrido por sí solo: esta clase está destinada a ampliarse, lo cual hacemos en nuestro módulo Emmet.js :

     

    // emmet.jsimport LegoCharacter from "./LegoCharacter";// Here we use the extends keyword to make// Emmet inherit from LegoCharacterexport default class Emmet extends LegoCharacter { constructor() { // super lets us call the LegoCharacter's constructor super( { actor: "Chris Pratt", character: "Emmet" } ); this.sayings = [ "Introducing the double-decker couch!", "So everyone can watch TV together and be buddies!", "We're going to crash into the sun!", "Hey, Abraham Lincoln, you bring your space chair right back!", "Overpriced coffee! Yes!" ]; }}

    Tanto LegoCharacter.js como emmet.js son archivos separados en nuestro proyecto; este será el caso de cada módulo de nuestro ejemplo. Dependiendo de cómo haya estado escribiendo JavaScript, esto puede parecerle un poco extraño. Sin embargo, cuando hayamos terminado, tendremos una versión "construida" que los combina.

    El index.js

    Nuestro index.js , otro archivo de nuestro proyecto, es el principal punto de entrada a nuestra biblioteca. Importa algunas clases de personajes de Lego, crea instancias de ellas y proporciona una función generadora de yielduna cita aleatoria cada vez que una persona que llama la solicita:

    // index.js// Notice that lodash isn't being imported via a relative path// but all the other modules are. More on that in a bit :)import _ from "lodash";import Emmet from "./emmet";import Wyldstyle from "./wyldstyle";import Benny from "./benny";import { getRandom } from "./utils";// Taking advantage of new scope controls in ES6// once a const is assigned, the reference cannot change.// Of course, transpiling to ES5, this becomes a var, but// a linter that understands ES6 can warn you if you// attempt to re-assign a const value, which is useful.const emmet = new Emmet();const wyldstyle = new Wyldstyle();const benny = new Benny();const characters = { emmet, wyldstyle, benny };// Pointless generator function that picks a random character// and asks for a random quote and then yields it to the callerfunction* randomQuote() { const chars = _.values( characters ); const character = chars[ getRandom( 0, chars.length - 1 ) ]; yield `${character.name}: ${character.saySomething()}`;}// Using object literal shorthand syntax, FTWexport default { characters, getRandomQuote() { return randomQuote().next().value; }};

    En pocas palabras, el módulo index.js importa lodash, las clases para nuestros tres personajes de Lego y una función de utilidad. Luego crea instancias de nuestros personajes de Lego y las exporta (las pone a disposición para consumir código), así como el getRandomQuotemétodo. Si todo va bien, cuando este código se transpile a ES5 debería hacer exactamente lo mismo.

     

    DE ACUERDO. ¿Ahora que?

    Tenemos todo este nuevo y brillante JavaScript, pero ¿cómo lo transpilamos a ES5? Primero, instalemos Babel usando npm :

    npm install -g babel

    La instalación de Babel de forma global nos brinda una babel opción de interfaz de línea de comandos (CLI) . Si navegamos al directorio raíz de nuestro proyecto y escribimos esto, podemos transpilar los módulos a ES5 y colocarlos en el directorio lib/ :

    babel ./src -d ./lib/

    Al mirar nuestra carpeta lib , veremos estos archivos en la lista:

    LegoCharacter.jsbenny.jsemmet.jsindex.jsutils.jswyldstyle.js

    ¿Recuerda que mencioné anteriormente que estábamos colocando cada uno de nuestros módulos ES6 en su propio archivo? Babel tomó cada uno de esos archivos, los convirtió a ES5 y los escribió en la misma estructura de archivos en nuestra carpeta lib . Un vistazo rápido a estos archivos puede revelarle un par de cosas:

    • Primero, estos archivos podrían consumirse en el nodo ahora mismo, siempre y cuando primero se requiera la dependencia del tiempo de ejecución de babel/register . Verá un ejemplo de estos ejecutándose en el nodo antes del final de esta publicación. (La transpilación generalmente implica una dependencia del tiempo de ejecución, aunque muchas de estas funciones, pero no todas, ahora están disponibles de forma nativa en el nodo v4 ).
    • En segundo lugar, todavía tenemos trabajo por hacer para que estos archivos puedan empaquetarse en un solo archivo, empaquetarse en una definición de módulo universal (UMD) y usarse en un navegador.

    Ingrese al paquete web

    Lo más probable es que hayas oído hablar de webpack , cuya descripción lo llama "un paquete para JavaScript y amigos". El caso de uso más común de webpack es actuar como paquete y cargador para un sitio web, lo que le permite agrupar su JavaScript, así como otros activos como CSS y plantillas, en uno (o más) archivos. webpack tiene un ecosistema asombroso de "cargadores", que son transformaciones aplicadas a archivos cargados por webpack. Si bien crear un UMD no es el caso de uso más común para webpack, resulta que podemos usar un cargador de webpack para cargar nuestros módulos ES6 y transpilarlos a ES5, y el proceso de agrupación de webpack para crear un único archivo de salida de nuestro proyecto de ejemplo. .

    Cargadores

    Utilizados ampliamente en webpack, los cargadores pueden hacer cosas como transpilar ES6 a ES5, Less a CSS, cargar archivos JSON, renderizar plantillas y mucho más. Los cargadores toman un testpatrón para usar para hacer coincidir los archivos que deben transformar. Muchos cargadores también pueden aceptar opciones de configuración adicionales, que utilizaremos. (¿Tiene curiosidad por saber qué otros cargadores existen? Consulte esta lista ).

    Sigamos adelante e instalemos webpack globalmente (lo que nos proporciona una CLI de paquete web ):

    npm install -g webpack

    A continuación podemos instalar babel-loader en nuestro proyecto local. Este cargador permite que webpack cargue nuestros módulos ES6 y los transpile a ES5. Podemos instalarlo y guardarlo en nuestro paquete.json devDependenciesejecutando esto:

    npm install --save-dev babel-loader

    Sin embargo, antes de que podamos usar webpack, necesitamos crear un archivo de configuración de webpack que le indique a webpack qué queremos que haga con nuestros archivos fuente. Generalmente llamado webpack.config.js , un archivo de configuración de webpack es un módulo de node.js que exporta un conjunto de valores de configuración que le indican a webpack qué hacer. Blog sopper tappers

     

    Aquí está nuestro archivo webpack.config.js inicial . He comentado mucho el código y también discutiremos algunos de los detalles importantes a continuación:

    module.exports = { // entry is the "main" source file we want to include/import entry: "./src/index.js", // output tells webpack where to put the bundle it creates output: { // in the case of a "plain global browser library", this // will be used as the reference to our module that is // hung off of the window object. library: "legoQuotes", // We want webpack to build a UMD wrapper for our module libraryTarget: "umd", // the destination file name filename: "lib/legoQuotes.js" }, // externals let you tell webpack about external dependencies // that shouldn't be resolved by webpack. externals: [ { // We're not only webpack that lodash should be an // external dependency, but we're also specifying how // lodash should be loaded in different scenarios // (more on that below) lodash: { root: "_", commonjs: "lodash", commonjs2: "lodash", amd: "lodash" } } ], module: { loaders: [ // babel loader, testing for files that have a .js extension // (except for files in our node_modules folder!). { test: /.js$/, exclude: /node_modules/, loader: "babel", query: { compact: false // because I want readable output } } ] }};

    Así que veamos un par de valores clave en nuestra configuración.

    Producción

    A un archivo de configuración del paquete web se le puede proporcionar un outputobjeto que describa cómo el paquete web debe compilar y empaquetar el código fuente. En nuestro ejemplo anterior, le estamos diciendo a webpack que envíe una biblioteca UMD a nuestro directorio lib/ .

    Exterioridad

    Es posible que hayas notado que nuestra biblioteca de ejemplo usa lodash. Queremos que nuestra biblioteca construida sea lo suficientemente inteligente como para requerir lodash de una fuente externa, en lugar de tener que incluir lodash en la salida. La externalsopción en un archivo de configuración de paquete web le permite especificar las dependencias que deben permanecer externas. En el caso de lodash, su clave de propiedad global ( _) no es la misma que su nombre (“lodash”), por lo que nuestra configuración anterior le indica al paquete web cómo requerir lodash para cada escenario de módulo determinado (CommonJS, AMD y raíz del navegador).

    El cargador de Babel

    Notarás que nuestro babel-loader simplemente se llama a sí mismo "babel" por el nombre del cargador. Esta es una convención de nomenclatura de paquetes web: donde el nombre del módulo es "myLoaderName-loader", el paquete web lo trata como "myLoaderName".

     

    Estamos probando cualquier archivo que termine en .js , excepto los archivos que se encuentran en nuestra carpeta node_modules/ . La compactopción que estamos pasando al cargador de Babel desactiva la compresión de espacios en blanco porque me gustaría que nuestra fuente compilada no minificada fuera legible. (Agregaremos una compilación minimizada en un momento).

    Si ejecutamos webpacken nuestra consola en la raíz del proyecto, verá nuestro archivo webpack.config.js y creará nuestra biblioteca, lo que nos dará un resultado similar a este:

    » webpackHash: f33a1067ef2c63b81060Version: webpack 1.12.1Time: 758ms Asset Size Chunks Chunk Nameslib/legoQuotes.js 12.5 kB 0 [emitted] main + 7 hidden modules

    Si miramos en nuestra carpeta lib/ , veremos un archivo legoQuotes.js recién creado. Esta vez, el contenido está empaquetado en el UMD del paquete web, que podemos ver en este fragmento:

    (function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' typeof module === 'object') module.exports = factory(require("lodash")); else if(typeof define === 'function' define.amd) define(["lodash"], factory); else if(typeof exports === 'object') exports["legoQuotes"] = factory(require("lodash")); else root["legoQuotes"] = factory(root["_"]);})(this, function(__WEBPACK_EXTERNAL_MODULE_1__) {// MODULE CODE HERE});

    Este UMD realiza un tipo de verificación de CommonJS, luego una verificación de AMD, luego otro estilo de CommonJS y finalmente vuelve a los valores globales simples del navegador. Puede ver cómo sabía buscar lodash como "lodash" si estábamos en un entorno CommonJS o AMD, y buscar _en la ventana (raíz) si estábamos tratando con navegadores globales simples.

    ¿Qué pasó exactamente?

    Cuando ejecutamos webpacknuestra consola, buscó el nombre predeterminado de un archivo de configuración ( webpack.config.js ) y leyó la configuración. A partir de ahí vio que el archivo src/index.js era nuestro principal punto de entrada y comenzó a cargarlo y sus dependencias (excepto lodash, que le dijimos que el paquete web era externo). Cada una de estas dependencias es un archivo .js , por lo que el cargador de Babel se ejecutaría en el archivo y lo transpilaría de ES6 a ES5 a medida que se cargara. A partir de ahí, todos los archivos cargados se escribieron en un único archivo de salida, legoQuotes.js , que se coloca en la carpeta lib .

    Al observar el código del módulo, verá que nuestra fuente ES6 efectivamente se ha transpilado a ES5. Por ejemplo, nuestra LegoCharacterclase ahora es una función constructora de ES5:

    // around line 179var LegoCharacter = (function () { function LegoCharacter(_ref) { var character = _ref.character; var actor = _ref.actor; _classCallCheck(this, LegoCharacter); this.actor = actor; this.name = character; this.sayings = ["I haven't been given any funny quotes yet."]; } _createClass(LegoCharacter, [{ key: "saySomething", value: function saySomething() { return this.sayings[(0, _utils.getRandom)(0, this.sayings.length - 1)]; } }]); return LegoCharacter;})();

    ¡Es utilizable!

    En este punto, podríamos incluir este archivo compilado tanto en un navegador (IE9+, como regla general) como en un nodo y funcionaría en cualquiera de ellos, siempre y cuando se incluya la dependencia del tiempo de ejecución de Babel.

     

    Si quisiéramos usar esto en el navegador, se vería así:

    !-- index.html --!DOCTYPE htmlhtmlhead meta charset="utf-8" meta http-equiv="X-UA-Compatible" content="IE=edge" titleLego Quote Module Example/title link rel="stylesheet" href="style.css"/headbody div blockquote/blockquote buttonGet Another Quote/button /div script src="../node_modules/lodash/index.js"/script script src="../node_modules/babel-core/browser-polyfill.js"/script script src="../lib/legoQuotes.js"/script script src="./main.js"/script/body/html

    Puede ver que hemos incluido nuestro archivo legoQuotes.js (justo debajo del archivo browser-polyfill.js de babel ) como cualquier otra scriptetiqueta (arriba). Nuestro archivo main.js , que utiliza nuestra biblioteca legoQuotes, tiene este aspecto:

    // main.js( function( legoQuotes ) { var btn = document.getElementById( "push_button redMore" ); var quote = document.getElementById( "quote" ); function writeQuoteToDom() { quote.innerHTML = legoQuotes.getRandomQuote(); } btn.addEventListener( "click", writeQuoteToDom ); writeQuoteToDom();} )( legoQuotes );

    Para usarlo en nodo, se vería así:

    require("babel/polyfill");var lego = require("./lib/legoQuotes.js");console.log(lego.getRandomQuote());// Wyldstyle: Come with me if you want to not die.

    Moviéndose a tragar

    Tanto la CLI de Babel como la de webpack son muy útiles, pero es común usar un ejecutor de tareas como Gulp para manejar la ejecución de este tipo de tareas. Esta coherencia puede resultar rentable si participa en muchos proyectos, ya que los principales comandos CLI que deberá recordar son: gulp someTaskName. No creo que haya una respuesta correcta o incorrecta aquí, en su mayor parte. Si prefiere las CLI, úselas. Usar Gulp es simplemente una forma posible de hacerlo.

    Configurar una tarea de compilación

    Primero, instalemos gulp:

    npm install -g gulp

    A continuación, creemos un archivo gulp que pueda ejecutar lo que hemos hecho hasta ahora. Usaremos el complemento webpack-stream gulp, que instalé ejecutando npm install –save-dev webpack-stream. Este complemento puede consumir nuestro archivo webpack.config.js y permitir que webpack funcione bien con gulp.

    // gulpfile.jsvar gulp = require( "gulp" );var webpack = require( "webpack-stream" );gulp.task( "build", function() { return gulp.src( "src/index.js" ) .pipe( webpack( require( "./webpack.config.js" ) ) ) .pipe( gulp.dest( "./lib" ) )} );

    Como estoy usando gulp para obtener nuestro index.js y escribir en el directorio de salida, modifiqué el archivo webpack.config.js eliminando entryy actualizando el archivo filename. También agregué un devtoolaccesorio, establecido en el valor de #inline-source-map(esto escribirá un mapa fuente al final del archivo en un comentario):

    // webpack.config.jsmodule.exports = { output: { library: "legoQuotes", libraryTarget: "umd", filename: "legoQuotes.js" }, devtool: "#inline-source-map", externals: [ { lodash: { root: "_", commonjs: "lodash", commonjs2: "lodash", amd: "lodash" } } ], module: { loaders: [ { test: /.js$/, exclude: /node_modules/, loader: "babel", query: { compact: false } } ] }};

    ¿Qué pasa con la minificación?

    ¡Me alegra que hayas preguntado! Un enfoque para minimizar se puede hacer usando el complemento gulp-uglify , junto con gulp-sourcemaps (ya que nos gustaría un mapa fuente para nuestro archivo min) y gulp-rename (que nos permite apuntar a un nombre de archivo diferente para que no lo hagamos). No sobrescribiremos nuestra versión no minificada). Agregué ambos a nuestro proyecto a través de:

     

    npm install --save-dev gulp-uglify gulp-sourcemaps gulp-rename

    En este enfoque, nuestra fuente no minificada seguirá teniendo un mapa fuente en línea, pero nuestro uso de gulp-sourcemaps a continuación hará que el mapa fuente del archivo minificado se escriba como un archivo separado (con un comentario en el archivo minificado que apunta al mapa fuente). archivo):

    // gulpfile.jsvar gulp = require( "gulp" );var webpack = require( "webpack-stream" );var sourcemaps = require( "gulp-sourcemaps" );var rename = require( "gulp-rename" );var uglify = require( "gulp-uglify" );gulp.task( "build", function() { return gulp.src( "src/index.js" ) .pipe( webpack( require( "./webpack.config.js" ) ) ) .pipe( gulp.dest( "./lib" ) ) .pipe( sourcemaps.init( { loadMaps: true } ) ) .pipe( uglify() ) .pipe( rename( "legoQuotes.min.js" ) ) .pipe( sourcemaps.write( "./" ) ) .pipe( gulp.dest( "lib/" ) );} );

    Si ejecutamos gulp builden nuestra consola, deberíamos ver algo similar a:

    » gulp build[19:08:25] Using gulpfile ~/git/oss/next-gen-js/gulpfile.js[19:08:25] Starting 'build'...[19:08:26] Version: webpack 1.12.1 Asset Size Chunks Chunk NameslegoQuotes.js 23.3 kB 0 [emitted] main[19:08:26] Finished 'build' after 1.28 s

    Nuestro directorio lib/ ahora contendrá tres archivos: legoQuotes.js , legoQuotes.min.js y legoQuotes.min.js.map . No sólo todos los que asisten aloprah show get un módulo, pero también obtienen un mapa fuente para hacer posible la depuración del archivo minificado.

    Complemento de banner de paquete web

    Si necesita incluir un encabezado de comentario de licencia en la parte superior de sus archivos creados, webpack lo hace fácil. Actualicé nuestro archivo webpack.config.js para incluir el archivo BannerPlugin. No me gusta codificar la información del banner si no es necesario, así que importé el archivo package.json para obtener la información de la biblioteca. También convertí el archivo webpack.config.js a ES6 y estoy usando una cadena de plantilla para representar el banner. Hacia la parte inferior del archivo webpack.config.js , puede ver que agregué una pluginspropiedad, siendo BannerPluginel único complemento que estamos usando actualmente:

    // webpack.config.jsimport webpack from "webpack";import pkg from "./package.json";var banner = ` ${pkg.name} - ${pkg.description} Author: ${pkg.author} Version: v${pkg.version} Url: ${pkg.homepage} License(s): ${pkg.license}`;export default { output: { library: pkg.name, libraryTarget: "umd", filename: `${pkg.name}.js` }, devtool: "#inline-source-map", externals: [ { lodash: { root: "_", commonjs: "lodash", commonjs2: "lodash", amd: "lodash" } } ], module: { loaders: [ { test: /.js$/, exclude: /node_modules/, loader: "babel", query: { compact: false } } ] }, plugins: [ new webpack.BannerPlugin( banner ) ]};

    (Nota: vale la pena mencionar que al convertir mi archivo webpack.config.js a ES6, ya no puedo ejecutarlo a través de la CLI del paquete web).

     

    Nuestro gulpfile.js actualizado incluye dos adiciones: la exigencia del gancho de registro de babel (en la línea 1) y la transferencia de opciones al complemento gulp-uglify:

    // gulpfile.jsrequire("babel/register");var gulp = require( "gulp" );var webpack = require( "webpack-stream" );var sourcemaps = require( "gulp-sourcemaps" );var rename = require( "gulp-rename" );var uglify = require( "gulp-uglify" );gulp.task( "build", function() { return gulp.src( "src/index.js" ) .pipe( webpack( require( "./webpack.config.js" ) ) ) .pipe( gulp.dest( "./lib" ) ) .pipe( sourcemaps.init( { loadMaps: true } ) ) .pipe( uglify( { // This keeps the banner in the minified output preserveComments: "license", compress: { // just a personal preference of mine negate_iife: false } } ) ) .pipe( rename( "legoQuotes.min.js" ) ) .pipe( sourcemaps.write( "./" ) ) .pipe( gulp.dest( "lib/" ) );} );

    ¿Que sigue?

    ¡Estamos en un buen camino hacia nuestro viaje! Hasta ahora, hemos realizado una rápida evolución en el uso de las CLI de babel y webpack para construir nuestra biblioteca, luego pasamos a usar gulp (y complementos relacionados) para manejar la compilación por nosotros. El código relacionado con esta publicación incluye un directorio example/ con un ejemplo basado en navegador y nodo de nuestro módulo transpilado en funcionamiento. En nuestra próxima publicación, veremos el uso de ESLint y JSCS para linting y formateo, mocha y chai para escribir pruebas, Karma para ejecutar esas pruebas y Estambul para medir nuestra cobertura de pruebas. Mientras tanto, es posible que desees consultar " Diseño de mejores API de JavaScript ", un artículo fantástico que puede ayudarte a escribir mejores módulos.

    Otras lecturas

    Escribir componentes reutilizables en ES6

    Escribir componentes reutilizables en ES6

    Clase magistral de diseño para una interfaz de usuario compleja, con Vitaly Friedman Design Token and UI Component Architecture, with Nathan Curtis Índice

    programar

    es

    https://aprendeprogramando.es/static/images/programar-escribir-componentes-reutilizables-en-es6-883-0.jpg

    2024-05-20

     

    Escribir componentes reutilizables en ES6
    Escribir componentes reutilizables en ES6

    Si crees que alguno de los contenidos (texto, imagenes o multimedia) en esta página infringe tus derechos relativos a propiedad intelectual, marcas registradas o cualquier otro de tus derechos, por favor ponte en contacto con nosotros en el mail [email protected] y retiraremos este contenido inmediatamente

     

     

    Top 20