Cómo desarrollar un cargador de paquetes web
¿Qué escenarios requieren escribir un cargador?
Una es escribir plantillas html en js, lo que puede resultar un poco inconveniente. Una es que no hay resaltado de sintaxis y la segunda es que debe encerrar cada línea entre comillas dobles o usar una inserción de matriz o algo así, por lo que si puede REQUIRIR un archivo html y luego convertirlo a la cadena js correspondiente, entonces Será más conveniente. (Si estás desarrollando con reaccionar, será más natural usar jsx). Busqué en la web y no encontré un cargador que cumpla mejor con los dos requisitos anteriores, así que intentaré escribir uno yo mismo.
Las plantillas JS generalmente tienen tres situaciones:
HTML puro, un archivo es una plantilla, que se puede convertir directamente en una cadena
Necesita una variable; un archivo tiene múltiples plantillas, cada plantilla corresponde a una variable
Un poco más complicado, la plantilla es una cadena generada por el requerimiento de otros módulos de fábrica
Ahora comencemos a escribir el cargar
El marco básico del cargador
Primero, cree una nueva carpeta html-template-loader en node_modules del proyecto y cree un nuevo archivo index.js en ella como cargador de archivos js. Esto agregará un cargador en webpack.config.js:
Agregar configuración del cargador
JavaScript
{
prueba: /\. tpl\.html$/,
loader: 'html-template-loader'
}
Con .tpl.html, esto significa que si incluyes un archivo que termina en .tpl.html en su código lógico, será procesado por este cargador
require tpl html
JavaScript
vartpl= require(". /dialog.tpl.html");
La clave es, ¿cómo se escribe el cargador?
El cargador también debe escribirse como un módulo. Un cargador básico se escribe así:
html-template-loader/index.js
JavaScript.
p>
/**
* La fuente del archivo original está en formato de cadena
*/
module.exports=function (fuente, mapa){
//Analiza la fuente
varexports=process(source);
return "module.exports = " exports; p>
}
Sí, has leído bien, el cargador es así de simple. La clave es comprender la mecánica del cargador: el cargador en realidad crea un módulo al final, y cuando necesitamos un archivo que el cargador debe analizar, se lo pasamos al cargador a través del retorno en la línea 7 anterior. -El cargador analizará automáticamente el contenido a cambio. El contenido de retorno es el contenido del módulo creado automáticamente. A diferencia de los módulos autoescritos habituales, este se escribirá en una cadena con sintaxis js legal.
El contenido exportado generado arriba es:
JavaScript
var?exports="var tpl = {email:'lt;divgt;1lt;/divgt; ', hola: 'lt;pgt;2lt;/pgt;'}";
return "var tpl = "tpl";\n module.exports = tpl;";
Entonces webpack creará automáticamente dicho módulo:
Módulo creado automáticamente por webpack
JavaScript
/***/ 109:
/***/función(módulo, exportaciones){
var?tpl={email:'lt;divgt;1lt;/divgt;', hola:'lt;pgt;2lt;/ pgt ;'};
module.exports=tpl;
/***/}
En mi proyecto, la identificación de este módulo es 109 y entonces el resultado devuelto por require es el objeto de este tpl.
Por otro lado, la inicialización obtiene el código fuente, es decir, webpack lee todo el contenido del archivo en formato utf-8 y lo pasa como una cadena como parámetro.
Ahora que el objetivo está claro, necesitamos procesar esta cadena fuente y devolver una cadena que pueda evaluarse. Es necesario definir los formatos de entrada y salida del cargador, lo cual también es derecho del desarrollador del cargador, mientras que el procesamiento intermedio no se revela al usuario.
Implementación específica del cargador
Divida el código fuente de todo el archivo en procesamiento línea por línea:
Divida el código fuente en línea por línea -procesamiento de línea
JavaScript
var?tpl=""
source.split(/\r?\n/ ).forEach(function(line) ){
line=line.trim();
if(!line.length){
return;
}
// Línea de proceso...
tpl =proceso(línea);
}
return?"module.exports = . .." )
La dificultad radica en cómo escribir la función de proceso en la línea 8 y cómo deletrear una cadena tpl legal.
Si es el primer caso anterior, es muy simple, simplemente agréguelo directamente
Si es el segundo caso, necesita usar variables para distinguir, entonces necesita; para usar la sintaxis para personalizar la Definición, dado que estamos usando html, necesitamos usar la función de resaltado.
Por lo tanto, considere usar etiquetas de comentarios html:
Utilice lt;! --VariableName--gt; Nombre de variable de definición de formato
lt;! --email--gt;
lt;divgt;
lt;pgt;hola mundolt;/pgt;
lt;/divgt; p>p>
lt;! --alert--gt;
lt;pgt;hilt;/pgt;
lt;spangt;manlt;/spangt
Nuestra sintaxis es lt; ;! -VariableName-gt;, al igual que las dos variables correo electrónico y alerta definidas anteriormente, una cadena de objeto se puede reconocer y escribir dentro de la función de proceso.
Si necesita introducir un módulo de terceros en el tercer caso, debe agregar el código de la función require en la última línea de retorno, es decir,
JavaScript
retorno?" var widget = require(./widgetFactory");\n"
"module.exports=widget.make()";
De manera similar, require debe definirse en el script. Sintaxis del código:
Formato de código dependiente
JavaScript
lt;script?generategt;varSELECT=require("js /select");lt;/ scriptgt;
Con la etiqueta de atributo generar, este código es el código del que se debe depender, lo que significa que debe deletrearse al frente.
La llamada normal es solo un script sin atributos:
lt;;! --email--gt;
lt;divgt;
lt;pgt ;hola mundolt;/pgt;
lt;/divgt;
lt;scriptgt;
widget.make()
lt;/scriptgt;
Finalmente conviértelo en un objeto.
Después del procesamiento adecuado, el módulo final generado tiene este aspecto:
JavaScript
/***/110:
/ * **/función(módulo, exportaciones, __webpack_require__){
var?widget=__webpack_require__(111);
var?tpl={
correo electrónico: ' lt;divgt;'
' lt;pgt;\'tpl\'lt;/pgt;'
'lt;pgt;hola mundolt;/pgt;' p>
'lt;/divgt;'
widget.make()
'lt;pgt.goodlt;/pgt;' ',
alerta: 'lt;pgt;hilt;/pgt;'
'lt;spangt;manlt;/spangt;' /p>
}
module.exports=tpl
/***/},
Se omite el código de procesamiento específico, consulte github para más detalles
Temas avanzados de cargadores
1. Los cargadores admiten el encadenamiento y los resultados del cargador anterior se pueden proporcionar al siguiente cargador. Por ejemplo, el cargador sass está escrito. así:
cargador sass
JavaScript
require("!style!css!sass! /file.scss"); >O escríbalo en el archivo de configuración:
webpack.config.js
JavaScript
{
test:/\.scss $/ ,
Cargadores: ["style", "css", "sass"]
}
Sass se procesa y se entrega al cargador CSS , css Después del procesamiento, se entrega al cargador de estilos y la transmisión de datos entre cargadores se completa a través de la función de devolución de llamada definida por el cargador. Antes de agregar otra línea, devuelva:
JavaScript
this.callback(null, source, map
Esto se puede pasar al siguiente cargador de carga, el cargador anterior debe tener el contenido devuelto
2. El cargador puede almacenar en caché, lo que puede acelerar
JavaScript
this.cacheable(); p>
3. Otros: el cargador admite asíncrono, la carga del cargador puede ser asíncrona, el cargador puede pasar parámetros, etc. Para obtener más detalles, consulte el documento oficial: CÓMO ESCRIBIR UN CARGADOR El documento oficial es relativamente sencillo y sencillo. no comienza desde 0 Se ha iniciado, pero no se ha realizado una demostración completa. Verifique por separado para obtener más detalles.
La clave para escribir un cargador es cómo compilar este archivo. El método anterior es dividirlo en archivos línea por línea y luego realizar un procesamiento simple. Generalmente, se utilizan árboles de sintaxis para la compilación.