用前端构建工具打包后端服务,我到底经历什么

node.js 能用 wepack打包么?node.js 代码可以打包成一个js 文件么?来这里看看吧

看到这个 标题,是的,我本是个后端,最近要写点 node.js, 之前写前端,知道 npm build 一下,那么用 javascript 写的后端程序也要 npm build 吧,好的,作为个 gopher , 带着对 javascript 的刻板印象就开干了。

我本 gopher,奈何没有一个会前端的老婆,就自己干前端了,如果干的不对,请及时纠正

项目背景

还是简单介绍下项目背景,屏幕前专业前端同学可以先猜猜这样干行还是不行,行的话,该怎么做。

这个程序运行的 node.js 端,提供一个简单的 http 服务,内部逻辑涉及:

  1. toml2json
  2. curl-to-go
  3. toml-to-go
  4. toml2xml
  5. xml2json
  6. json2toml

这些逻辑,可用内建包能解决,有些依赖第三方包,例如:

  1. json2toml
  2. object-to-xml

还有些组件,未提交到npm,也未做模块化处理,需要把代码找出来,单独处理,例如:

  1. curl-to-go
  2. toml-to-go

这些第三方包,感觉都是运行在前端环境的,(刚开始,我只是通过npm拉下来,也不知道能不能运行在 node.js 上,npm 也没指明这些包在前后端 runtime 兼容性)现在我想用 webpack 将其所有的代码打包成一个 js 文件,并能运行在 node.js 环境,

好,问题和背景如上。

别说:node.js 打什么包!

钟薛高 你还要不要

开整

我面临如下问题:

  1. 如何引入前端 包
  2. 如何引入 未模块化改造的包
  3. 如何让 webpack 编译的成果在 node.js 环境也能运行

关于第一个问题,首先得搞清楚在 Javascriptimportrequire 区别。

import 与 require 区别

require/exports 属于社区自己选举出的方案。import/export 属于是 ECMAScript 规范。

这里我们用到了 webpack , 那么就得使用 import/export 作为代码引入语法。所以,对 curl-to-go 代码改一下,在最后新增:

function curlToGo(curl) {
...
}

+ export default curlToGo;

这样就解决了,各个js文件组合问题。

第二个问题,需要弄清楚,node.js 的包管理机制

node.js 模块

node.js 模块管理,用的是 require ,由于我需要用 node.js 起一个 http 服务,需要使用 require 语句引入 http 模块。

但这还没完,webpack 是不能很好区分,哪些是外部依赖,哪些是内部依赖。所以这里需要告知 webpack :

module.exports = {

    target: "node", 

    }

第三个问题,那就随缘了,build之后,run一下试试咯。

最终 webpack 配置如下。

--- a/webpack.config.js
+++ b/webpack.config.js
@@ -1,5 +1,6 @@
 const path = require('path');
 const webpack = require('webpack');
+var fs = require("fs")

 /*
  * 引入 ParallelUglifyPlugin 插件
@@ -13,9 +14,20 @@ const PATHS = {
     build: path.join(__dirname, 'build'),
 };

+var nodeModules = {};
+fs.readdirSync('node_modules')
+    .filter(function(x) {
+        return ['.bin'].indexOf(x) === -1;
+    })
+    .forEach(function(mod) {
+        nodeModules[mod] = 'commonjs ' + mod;
+    });
+
 module.exports = {
     mode: 'development',
     devtool: false, // 编译成果 保留换行
+    target: "node",
+    externals: nodeModules,
     entry: {
         entry: path.join(__dirname, 'src/index.js'),
     },

最后

又是折腾前端的一天,哦不,是好几天。

javascript 和 node.js 包都放在 npm 里,有点让人搞不清楚适用环境,当然,这次引入的包都没有调用底层 API,所以,没出现兼容性问题。

importrequire 傻傻分不清楚,CommonJS, ES6ES5 各种标准算是给我好好上了一课。

好了,简单聊到这,不是太难的东西,只是表达一下一个刚入门前端的人碰到这些问题后的,“幸”路历程。

参考

  • https://zhuanlan.zhihu.com/p/28483358
  • https://sazzer.github.io/blog/2015/05/12/Javascript-modules-ES5-vs-ES6/
  • https://juejin.cn/post/6896397110078504973
  • https://zh.quish.tv/how-package-nodejs-application-using-webpack
  • https://blog.anymelon.com/2020/05-22-nodejs-webpack-record/
  • https://www.zhihu.com/question/56820346