Back-end en componentes de archivo único VueJS

Un día, mientras leía la documentación de Vue Loader, me encontré con una innovación interesante en la versión 15. Estamos hablando de bloques personalizados que se pueden incrustar en componentes de un solo archivo de Vue. El ejemplo muestra cómo puede acceder al contenido de este bloque directamente en el componente. Al principio no parecía darle mucho valor a esta oportunidad, pero luego pensé, hmm ... y si rellenaba la parte de atrás conectada con esta parte del frente ... Y nos vamos ...


La copia de seguridad en ese momento (hace un año) estaba en php . Para comenzar, decidí ver cómo mi editor favorito de PhpStorm manejaba la inserción de código php en este bloque. No importa cómo lo intenté, no se habló de ningún resaltado de código u otras funciones de autocompletar. Creo que escribiré una pregunta en soporte técnico para JetBrains. Después de un tiempo, recibí una respuesta negativa sobre cualquier posibilidad de configurar esto, pero me enviaron instrucciones sobre cómo configurarlo para javascript. Bueno, creo que está bien, aún debes intentar implementar la idea. Nunca he tenido que desarrollar nada para Webpack antes. Estudié la documentación del día, y durante las siguientes dos noches desarrollé Loader y el complemento. Todo esto funcionó, pero sin el resaltado de sintaxis elemental en bloques personalizados .vue, el código php solo trajo dolor ...


El tiempo paso Poco a poco, familiarizándome con nodejs y siguiendo el registro de cambios en las nuevas versiones, encontrando soluciones útiles y listas para mí, comencé a comprender que al elegir en qué escribir respaldar, todavía usaré el nodo. Ejecutar múltiples copias de aplicaciones en el nodo y descargar la carga en estas copias usando ngnix dio mejores resultados. Recientemente volví a este tema y finalicé el cargador y el complemento.


Comenzaré con la plantilla


Plantilla de backend


La plantilla es un espacio en blanco en el que deben caer las piezas de back-end de bloques personalizados de archivos vue. Todo esto después del procesamiento se almacena en el archivo resultante. Ejemplo de plantilla:


Plantilla de backend
const WEB_PORT = 314; const Koa = require('koa'); var Router = require('koa-router'); const app = new Koa(); var router = new Router(); app .use(router.routes()) .use(router.allowedMethods()); const body = require('koa-json-body')({ limit: '10kb' }); app.listen(WEB_PORT); app.context.db = require('../lib/db.js'); /*{{endpoints}}*/ 

/*{{endpoints}}*/ - este es el lugar donde se insertará el código de los bloques personalizados


Cargador de paquetes web


Código del gestor de arranque
 var loaderUtils = require("loader-utils"); var path = require('path'); const id = 'gavrilow_backend_plugin'; exports.default = function (source) { this.cacheable(); //      // !!!   ,         this.async()(null, ''); //    .   . const _source = source.replace(/^\n/img, ''); //       Custom Block [blockType=backend] const file_path = this.resourcePath; // this._compiler -  ,     if (this._compiler[id] === undefined) this._compiler[id] = { change: true, arr: [] }; var fp_exists = false; //         Custom Blocks vue //   -   . for (let i = this._compiler[id].arr.length - 1; i >= 0; i--) { if (this._compiler[id].arr[i].file_path === file_path) { fp_exists = true; //  ,     . if (this._compiler[id].arr[i].data !== _source) { //             ,    this._compiler[id].arr[i].data = _source; this._compiler[id].change = true; } break; } } if (fp_exists) return; //         ,   //     ,   Custom Blocks      //    [ change = true ]     . this._compiler[id].change = true; this._compiler[id].arr.push({ file_path: file_path, data: _source }); }; 

Los archivos * .vue que contienen bloques personalizados ingresan al gestor de arranque. El nombre del bloque personalizado se puede configurar usted mismo.


Complemento de paquete web


Código de complemento
 const fs = require('fs'); const util = require('util'); const readFile = util.promisify(fs.readFile); const writeFile = util.promisify(fs.writeFile); var footer_header_template; class gavrilow_backend_plugin { constructor(options) { this.options = options; this.logMess = ''; } endLog(){ this.logMess = '------ gavrilow-backend-plugin ------------------------------------------------------------------\n' +this.logMess; this.addLogMess('-------------------------------------------------------------------------------------------------'); console.log(this.logMess); this.logMess = ''; } addLogMess(mess){ this.logMess += mess+'\n'; } async prepareTemplate(){ try { if (footer_header_template === undefined) { let contents = await readFile(this.options.backend_template, "utf-8"); footer_header_template = contents.split(/^\/\*+?{{.*endpoints.*}}+?\*\/$/img); if (footer_header_template.length !== 2) { footer_header_template = undefined; this.addLogMess('     .'); this.endLog(); return false; } else return true; } else return true; } catch (err) { footer_header_template = undefined; throw err; } } apply(compiler) { compiler.hooks.emit.tapAsync( 'gavrilow_backend_plugin', (compilation, callback) => { callback(); if (this.options.backend_template === undefined || this.options.backend_template === '') { this.addLogMess('  /  -  ...'); this.endLog(); return; } if (this.options.backend_output === undefined || this.options.backend_output === '') { this.addLogMess('     js   ...'); this.endLog(); return; } if (!compiler.gavrilow_backend_plugin) { this.addLogMess('         [ <backend>...</backend> ].'); this.endLog(); return; } (async ()=>{ try { //   if (!await this.prepareTemplate()) return; //        -  if (!compiler.gavrilow_backend_plugin.change) return; //       //   compiler.gavrilow_backend_plugin.change = false; if (compiler.gavrilow_backend_plugin.arr.length === 0) { this.addLogMess(' -      [ <backend>...</backend> ]'); this.endLog(); return; } this.addLogMess(' beckend: "'+this.options.backend_output+'"\n...'); //     /*{{endpoints}}*/   var backend_js = footer_header_template[0]+"\n"; //     Custom Blocks for (let i = 0; i < compiler.gavrilow_backend_plugin.arr.length; i++) { backend_js +=compiler.gavrilow_backend_plugin.arr[i].data+"\n"; this.addLogMess('['+compiler.gavrilow_backend_plugin.arr[i].file_path+']'); } //     /*{{endpoints}}*/   backend_js += footer_header_template[1]; //    await writeFile(this.options.backend_output, backend_js); } catch (err) { throw err; } finally { this.endLog(); } })(); } ); } } gavrilow_backend_plugin.loader = require.resolve('./loader'); module.exports = gavrilow_backend_plugin; 

El complemento se activa cuando se construye el proyecto La plantilla se prepara dividiéndola en 2 partes: antes /*{{endpoints}}*/ y después /*{{endpoints}}*/ Si se estableció el indicador para cambiar la matriz por el cargador, el guión final se ensambla a partir de todas las partes disponibles.




Cómo probarlo todo


El proyecto se inundó en github .


También hay una descripción de la configuración.

Source: https://habr.com/ru/post/es436592/


All Articles