最近在研究一款基于nodejs的CMS,后台使用nodejs搭建的,前台可以原生HTML,或者使用vuejs,react,构建工具使用webpack&gulp&sass。
基于nodejs的CMS,要比市场上那些PHP,JAVA等后台要轻便得多,即可以节约服务器成本,维护起来也方便,所以值得大家去探讨和研究。今天分享不是CMS,而是我部署的时候一些坑。
问题来源
基于nodejs的CMS已经安装完毕,是没问题的。但是我使用的内置的构建工具gulp进行压缩CSS,JS或者image的时候,问题就来了,可以先看张图:
一直提示:ES模块不支持。其实如果您不了解nodejs下面对于ES模块的兼容问题的话,估计这问题会坑死你。你可以按照他的提示去处理,比如去掉type:module,或者把.js改成.cjs,然后继续运行。
并且尝试用require改成es6里的import和export,发现新的错误又来了。
文字错误:提示你不能import外面的module,所以此方法行不通哦。于是我找了些资料,如何让ES6在node下面运行。于是找到此方法:
nodejs不支持import语法,如果要支持,需要babel来支持。
所以我们来安装babel吧, 有了babel, 能够使用更多高级词法!
在项目根目录下,执行:
npm install --save babel-corenpm
install --save babel-preset-env 或者 npm install --save babel-preset-es2015npm
install babel-cli -g
接着在项目根目录下
创建一个名字为.babelrc
的文件, 文件内容入如下( 要注意window系统下创建这种文件系统会提示你:"必须键入文件名" , 你可以找别的方式去创建, 我是在开发工具的工程目录中把这个文件创建出来的,也可以用cmder神器的vim命令
):
{
"presets": [
"es2015"
],
"plugins": []
}
或者:
{
"presets": [
"env"
],
"plugins": []
}
到目前为止babel算是安装完毕了。开心了,应该没问题了吧,于是尝试运行,没啥用哦,还是同样的报错。
插件版本问题
有时候版本问题会直接影响程序的运行,所以大家必须牢记。
继续回到上面提到的问题,查看了安装的一些插件,进行了一系列的更新,然而事与愿违,还是行不通。
CMS主题脱离NODE
几个小时过去了,上面的方法我都尝试了,发现还是解决不了。于是我把基于CMS的主题模板复制到外面去,单独去建一个项目,然后使用gulp去构建合并压缩,发现还是同样的问题,此时此刻,心态已到奔溃边缘了。
出去喝杯茶调整下,看来只有使用最后的绝招,先新建一个空壳的框架,然后把主题模板的插件和代码一个个移动进去,进行对比,结果真被我找到了。祸根就是gulpfiles里面这个插件模块:
const beeper = require('beeper');
我把它注释掉了,就可以解决上图1和图2的问题了。
但是在运行过程中又出问题了:
[object Object] is not a PostCSS plugin
gulp/node_modules/gulp-postcss/node_modules/postcss/lib/processor.js:143
throw new Error(i + ' is not a PostCSS plugin');
^Error: [object Object] is not a PostCSS plugin
at Processor.normalize (/Applications/XAMPP/xamppfiles/htdocs/sites/gulp/node_modules/gulp-postcss/node_modules/postcss/lib/processor.js:143:15)
at new Processor (/Applications/XAMPP/xamppfiles/htdocs/sites/gulp/node_modules/gulp-postcss/node_modules/postcss/lib/processor.js:51:25)
at postcss (/Applications/XAMPP/xamppfiles/htdocs/sites/gulp/node_modules/gulp-postcss/node_modules/postcss/lib/postcss.js:73:10)
at Transform.stream._transform (/Applications/XAMPP/xamppfiles/htdocs/sites/gulp/node_modules/gulp-postcss/index.js:47:5)
at Transform._read (_stream_transform.js:167:10)
at Transform._write (_stream_transform.js:155:12)
at doWrite (_stream_writable.js:300:12)
at writeOrBuffer (_stream_writable.js:286:5)
at Transform.Writable.write (_stream_writable.js:214:11)
at DestroyableTransform.ondata (/Applications/XAMPP/xamppfiles/htdocs/sites/gulp/node_modules/gulp-sass/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:531:20)
Mac-a45e60e72dad:gulp JoeKonst$
爬坑之路还未完成,继续查找,此时此刻,我去谷歌搜索了,结果在stackoverflow上面找到了解决方案。
提示我更新了插件的postCSS版本,然后最最最重要一步就是执行命令:
npm i -d postcss
使得它跟系统其他插件相关联起来了。于是继续运行下程序,如下图所示:
看到上图,大功告成,终于松了口气,折腾一下午的时间没有白费。
解决方案总结
总结爬坑之路,问题主要根源是:beeper模块和postCSS关联,我们是注释了beeper模块,也就是说在框架里,我们不能使用它了,所以此方法或者有些不妥,但是对于现状来说,还是可以的。
如果我们在以后更大的项目里,应该采取更稳妥的方法去解决,也就是要让node下面去兼容ES6模块,这里我归纳了一种方案,供大家参考。以实例说明,请往下看。
在编写nodejs代码中想要引进我的一个工具函数包 utils.js 。里面的代码结构如下:
//utils.js
export const funA = () => {} ; //函数funA
export const funB = () => {} ; //函数funB
在其它js文件中使用ES6 import语法 import * as Utils from './utils' 中都没问题,但是在nodejs中用import,启动 node serve.js时候会报语法错误(除非用 babel-node serve.js 编译ES6)。这是由于nodejs中部分ES6语法还没有标准化,还不能直接支持(今后新版本可能会支持哦~~),需要安装 babel-cli 去支持。
解决方案
大家都知道node中通常引入模块是 require 语法,而非import语法。 那么怎么编写一个js文件 即支持require 语法,又支持import语法呢。
//utils.js
const funA = () => {} ; //函数funA
const funB = () => {} ; //函数funB
module.exports = {
funA:funA,
funB:funB,
}
这样node中也可以用require 引进:
//nodejs
//service.js
const Utils = require('./util')
启动node服务器 node serve.js 就不会报错啦。(注:service.js为nodejs的入口文件)
大家可以按照上面的方法去尝试下,如果你还有问题,可以留言或者加入QQ群咨询。