一、废话前言!哈哈哈!
注意:不用perl语言,使用python、java、go等开发web的同样适用,均可以读一下。
Mojolicious专栏很长时间没更新了。原因种种(主要是自己开了一个小网站,在研究着写点Perl语言的初学教程。还有就是今年主要在用python,在自己闷头搞运维自动化——用Ansible)。
前面一篇文章中提到过,我之前写前端主要用vue框架。Vue框架学起来是简单,用起来也简单,但是主要做单页面应用。对于我们个人开发来说,想要的效果是“边开发,边使用”,“想到什么功能,写什么功能”。当我的小系统真正投入使用时,我发现vue并不适合这种开发方式。主要还是在于webpack打包编译方面,每次想要增加什么功能,都要找回前端vue源代码重新打包,然后再去正式系统替换文件,过于繁琐。
正因如此,我花了些时间学习了jquery,打算用jquery+bootstrap开发多页面应用。嗯,用php试了试,效果还可以。
还是前段时间做Ansible的时候,我用python的Flask写了一个web控制台,用的是cookiecutter-flask模板。在使用过程中,我发现最新版的模板,前端使用的webpack,通过npm的方式安装jquery和bootstrap,并把jquery、bootstrap打包到了一起。
最令我惊艳的功能是,在开发模式模板将前端webpack启动的nodejs开发server和flask run测试sever连接到了一起,可以通过热开发模式直接同时验证前端和后端功能,真正实现了前后端一起开发。
正巧前天出差,在路上跑了一天闲来无事,在长途车上把webpack官方文档看了一遍,昨天又研究了一天,把webpack和mojolicious给集成了。
废话说的够多了,现在讲讲方法:
二、必要条件
首先你得有一套perl,linux自带,windows可以用strawberry perl。通过CPAN安装mojolicious。
然后,你得有一套nodejs。
上面这些的安装和使用教程请自行百度。不再赘述。
首先,使用mojo命令生成一个mojolicious项目:
生成的项目目录如下:
三、准备webpack
在终端进入my_app目录下,使用npm init创建一个package.json配置文件:
如果比较懒,可以像我一样一溜回车搞下来。现在,我们就可以开始配置webpack了。
到这一步,我就要跳过webpack基础配置,因为涉及到webpack文件均和官网教程一样,没有任何区别,参照官网指南一步一步配置即可。
当然了,不想一步一步的配置,可以直接使用我已经做好的文件:
liudashang/webpack打包文档gitee.com将上述文件和你生成好的mojolicious合并,如下:
注意:
开始与mojolicious集成以前,有两处需要注意的地方:
1.github中的文件,默认是myapp目录同级的情况,如果想与my_app目录下部署,则需要修改webpack.common.js文件中两处代码:
(1)output的path项,此项代表着.js .css和图片等静态文件的生产模式也就是编译后放置的目录,具体指向的是mojolicious的public目录下的dist文件夹。(做过mojolicious的知道,在html引用时,使用的是‘/dist/index.js’这种url形式)
(2)plugins中修改manifest.json的生成位置,建议与mojolicous的my_app.conf文件在一起。接下来会说明这个插件的用处。
2.webpack中文网中的教程,有一部是错误的,就是css文件分离中提到的extract-text-webpack-plugin插件,这个插件默认安装方式不支持4.0版本,如果坚持使用需要:
npm install --save-dev extract-text-webpack-plugin@next
或者,像我一样选择mini-css-extract-plugin,这是webpack官方推荐的4.0版本分离方式。
四、webpack与mojolicious连接
说完了上面准备工作,我就讲讲后端的mojolicious框架,如何动态的绑定前端的webpack的。
首先,我们在mojolicious中,后台引入css和js文件,无疑使用的都是html的css标签和javascript标签。一般而言,要引入jquery、bootstrap和echarts等库,我们只要固定指向这些文件即可。
但是webpack打包的文件,一般是带有hash值的,类似这样:
这些带有hash值的文件名,每次修改js文件都会变得不同。对于后端而言,我们需要有一种方式,能够动态的获取到css、js的文件名,无论是在开发模式从webpack dev server中获取静态文件,还是在生产模式无需配置、自动的生成引用js和css的url链接。让我们能够专注于开发,而无需关注这些繁琐的配置。
而这,恰恰是webpack中manifest-revision-webpack-plugin插件的功能:
manifest插件会自动的将每次生成的js和css文件信息写到一个manifest.json文件(如上图所示)中,在前面提到的注意中(2)目的便是要修改这个manifest.json文件的存放位置。
看到上图中的信息,大家会有一个疑问吧,就是assets和publicPath,assets很好理解即静态文件信息,而publicPath是何物?
这就需要理解webpack开发方式了,用过webpack或者使用过vue cli的可能会知道,在前端开发模式下,所有的静态文件有http://localhost:8080服务提供,我们需要访问这个网址获取静态文件;而在生产模式真正使用mojolicious时,我们的url一般是"/dist/index.js"、"/dist/index.css"这种,即直接从后台public目录下获取。而publicPath的目的,就是要告诉mojolicous在渲染html.ep文件时,开发模式需要url应该设置为"http://localhost:8080/dist/index.js",生产模式下应该设置为“/dist/index.js”类似的形式。
体现在开发模式和生产模式下这两者的不同之处的配置信息,在于webpack.prod.js(生产)和webpack.dev.js(开发)配置文件中:
manifest插件会自动引述上面的配置信息到manifest中。只要js和css资源发生改变,webpack便会自动重新写入manifest.json文件。
对于不用perl,而用python、go和java的用户来讲,同样可以使用我的webpack配置进行打包和开发,只要根据各个语言自身的情况将manifest.json中的信息渲染为html中css、js标签的url连接并且可以在开发模式下动态更新即可。
现在,我们有了一个动态更新js/css等静态文件url的配置信息,那么如何调用给mojolicious后台使用呢?方法同样简单,我们可以使用Mojolicious::Plugin::JSONConfig插件,这个插件继承自Mojolicious::Plugin::Config,Config插件主要用来获取my_app.conf中的配置信息,而JSONConfig顾名思义就是用来读取my_app.json中的配置信息了。
Config插件读取的信息会保存在一个全局变量$config中,而且这个全局变量可以直接在html.ep中调用,比如:
%= config->{secret}
我们可以利用这一特性,将manifest.json的信息导入到mojolicous中去了:
在lib目录下MyApp.pm中插入语句,与my_app.conf放在同级目录下,可以直接使用该语句,如果不在该目录下,需要在'manifest.json'字符串前加路径字符串:
这样,我们就可以从config变量中生成我们需要的url了,修改layout下的default.html.ep代码:
这样,我们就可以根据manifest.json获取我们需要静态文件了。
最后,还有一点需要注意,config是随着mojolicious框架启动而加载的,默认情况发生变化不会更新任何变量值。对于生产环境来说,并无不妥。但是对于开发环境来说,webpack dev server发生了变化,而后端没变就有问题了。
但是如果使用morbo命令进行开发测试,-w 文件/文件夹 选项可以启用热重载功能,确保manifest.json发生变化后,后端实时重载。
morbo默认监视templates和lib目录下的变化,如果使用-w选项会覆盖默认值,所以必须要把所有需要监视的文件或目录都加上:
morbo script/my_app -w lib -w templates -w pulic -w manifest.json
好了,现在我们就可以愉快开发了。