VueJS单一文件组件中的后端

有一天,在阅读Vue Loader文档时,我遇到了版本15中的一项有趣的创新。 我们正在谈论可以嵌入Vue的单文件组件中的自定义块 。 该示例说明如何直接在组件中访问此块的内容。 起初,我似乎并不太重视这个机会,但是后来我想,嗯……如果我把后背塞满了与这块前脸相连的……那我们就走了……


当时(一年前)的备份是在php上进行的 。 首先,我决定看看我最喜欢的PhpStorm编辑器如何将php代码插入此代码块。 无论我如何尝试,都没有谈论任何代码突出显示或其他自动完成功能。 我想我会为JetBrains提供技术支持方面的问题 。 一段时间后,我收到关于是否有可能进行配置的否定回答,但是他们发送了有关如何为javascript配置它的说明。 好吧,我认为可以,您仍然需要尝试实现这一想法。 之前我从来没有为Webpack开发任何东西。 我研究了当天的文档,然后在接下来的两个晚上开发了Loader和插件。 所有这些都有效,但是在自定义.vue块中没有突出显示基本语法的情况下,php代码只会带来痛苦...


时间过去了。 慢慢熟悉nodejs并跟踪新版本中的更改日志,为自己找到有用的现成的解决方案,我开始理解,在选择要写的内容时,我仍然会使用该节点。 在节点上运行应用程序的多个副本,并使用ngnix卸载这些副本上的负载可获得更好的结果。 最近,我回到了这个主题,并完成了加载程序和插件。


我将从模板开始


后端范本


模板是空白,来自自定义vue文件块的后端片段应落入其中。 处理后的所有这些都存储在结果文件中。 模板示例:


后端模板
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}}*/ -这是将插入自定义块中的代码的地方


Webpack加载器


引导程序代码
 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 }); }; 

包含自定义块的* .vue文件进入引导加载程序。 定制块的名称可以自行设置。


Webpack插件


插件代码
 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; 

该插件在项目组装完成时触发。 通过将模板分为两部分来准备模板: /*{{endpoints}}*/之前/*{{endpoints}}*/之后/*{{endpoints}}*/如果设置了用于由加载程序更改数组的标志,则最终脚本将从所有可用的部分组合而成。




如何尝试全部


该项目充斥在github上


还有设置的描述。

Source: https://habr.com/ru/post/zh-CN436592/


All Articles