使用webpack打包koa2 框架app


Posted in Javascript onFebruary 02, 2018

以前在用koa写server的时候,发布简直是噩梦。需要将src里面的全部文件都覆盖掉,config配置文件也要覆盖,稍有不慎就会线上报各种各样的问题,然后就得回退,本地调好在发布。偶然看见一篇文章讲 如何使用webpack打包koa app ,惊为天人,原来webpack也能打包后台。这在以前想都没想过。

关键问题

一:所有node_modules里的模块都不进行打包

webpack的核心功能是将引用的各个模块打到一个文件里,并会将各种规范的模块进行统一的模块化处理(webpack规范)。

然而node中包含大量的fs、path操作,这些fs和path操作在打包完成后将没有操作对象,还会报出很多各样的错误。

所以使用webpack打包的核心就是拒绝打包一切node_modules里的模块,只是将相对路径引用的文件打包到一个文件里。恰巧我们发现webapck提供externals属性来排除掉不需要打包的模块。

再深入点我们可以发现:像webpack、nodemon、babel-preset-env这样的模块是app开发环境依赖的包,我们的程序里根本不会require这些模块。

综上可以发现:我们只将所有require到的包排除掉就可以了,这个模块对应的也就是package.json里dependencies下的模块。有关dependencies和devDependencies的区别要理解好。

因此我们可以使用externals-dependencies这个插件配合externals属性实现dependencies的排除工作。

代码:

const webpack = require('webpack');
const _externals = require('externals-dependencies')
module.exports = {
  ...
  externals: _externals(),
  ...
}

二:target指向node

官方文档:编译为类 Node.js 环境可用(使用 Node.js require 加载 chunk)

代码:

target: 'node',

三:增加node配置

官方文档:这些选项可以配置是否 polyfill 或 mock 某些 Node.js全局变量和模块。这可以使最初为 Node.js 环境编写的代码,在其他环境(如浏览器)中运行。

代码:

node: {
    console: true,
    global: true,
    process: true,
    Buffer: true,
    __filename: true,
    __dirname: true,
    setImmediate: true,
    path: true
},

四:babel配置

为了兼容低版本的node不原生支持async/await的问题。这里babel我使用了babel-preset-env{"modules": false}的配置。此配置会将es6语法转为es5语法,例如let、const转为var。

同时将所有的async/await函数也转成了polyfill里定义的_asyncToGenerator函数。

function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }

其实是使用promise实现了async函数的功能。

当然这个函数在运行时还需要regeneratorRuntime函数。所以我在全局引入了babel-polyfill来提供regeneratorRuntime函。

注:如果你的node版本很高且原生支持async/await,大可将babel-preset-env和babel-polyfill省略掉

代码:

const path = require('path');
const webpack = require('webpack');
const _externals = require('externals-dependencies')

module.exports = {
  entry: {
    app: [
      // 如果polyfill放在这里,打包的时候将不会被external,必须在js里require才能有效external
      // 'babel-polyfill',
      './src/index.js'
    ]
  },
  output: {
    path: path.resolve(__dirname),
    filename: '[name].js'
  },
  resolve: {
    extensions: [".js"]
  },
  target: 'node',
  externals: _externals(),
  context: __dirname,
  node: {
    console: true,
    global: true,
    process: true,
    Buffer: true,
    __filename: true,
    __dirname: true,
    setImmediate: true,
    path: true
  },
  module: {
    rules: [
      {
        test: /\.js/,
        use: ['babel-loader']
      }
    ]
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: '"development"'
      }
    }),
  ]
}

部署

经过打包,部署的时候就方便多了,只需要将package.json、app.js、以及view里的html部署上线就好了。然后在服务器上执行

1. npm install
2. npm run for

然后server就后台运行了。如果需要更新发布,只需要本地重新npm run dev或npm run build打好包,拖到服务器覆盖app.js即可。

Javascript 相关文章推荐
Display SQL Server Version Information
Jun 21 Javascript
jQuery bind事件使用详解
May 05 Javascript
JS打开层/关闭层/移动层动画效果的实例代码
May 11 Javascript
js获取本机的外网/广域网ip地址完整源码
Aug 12 Javascript
jQuery对指定元素中指定字符串进行替换的方法
Mar 17 Javascript
AngularJs自定义服务之实现签名和加密
Aug 02 Javascript
javascript中数组(Array)对象和字符串(String)对象的常用方法总结
Dec 15 Javascript
jQuery html表格排序插件tablesorter使用方法详解
Feb 10 Javascript
无循环 JavaScript(map、reduce、filter和find)
Apr 08 Javascript
JS中定位 position 的使用实例代码
Aug 06 Javascript
如何利用vue+vue-router+elementUI实现简易通讯录
May 13 Javascript
三分钟教你用Node做一个微信哄女友(基友)神器(面向小白)
Jun 21 Javascript
Vue组件化开发思考
Feb 02 #Javascript
微信小程序实现导航栏选项卡效果
Jun 19 #Javascript
解析Vue.js中的组件
Feb 02 #Javascript
如何将你的AngularJS1.x应用迁移至React的方法
Feb 01 #Javascript
vue 2.0 购物车小球抛物线的示例代码
Feb 01 #Javascript
js中getBoundingClientRect的作用及兼容方案详解
Feb 01 #Javascript
深入剖析Express cookie-parser中间件实现示例
Feb 01 #Javascript
You might like
配置支持SSI
2006/11/25 PHP
php 图片加水印与上传图片加水印php类
2010/05/12 PHP
PHP5中Cookie与 Session使用详解
2013/04/30 PHP
php使用GeoIP库实例
2014/06/27 PHP
php 删除指定文件夹的实例讲解
2017/07/25 PHP
PHP通过文件路径获取文件名的实例代码
2018/10/14 PHP
TNC vs BOOM BO3 第一场2.13
2021/03/10 DOTA
用CSS+JS实现的进度条效果效果
2007/06/05 Javascript
firefox事件处理之自动查找event的函数(用于onclick=foo())
2010/08/05 Javascript
JavaScript动态修改弹出窗口大小的方法
2015/04/06 Javascript
js封装tab标签页实例分享
2016/12/19 Javascript
javascript中this用法实例详解
2017/04/06 Javascript
addEventListener()与removeEventListener()解析
2017/04/20 Javascript
JS实现禁止高频率连续点击的方法【基于ES6语法】
2017/04/25 Javascript
JavaScript 数组的进化与性能分析
2017/09/18 Javascript
关于express与koa的使用对比详解
2018/01/25 Javascript
jQuery表单元素过滤选择器用法实例分析
2019/02/20 jQuery
微信小程序页面上下滚动效果
2020/11/18 Javascript
js编写简易的计算器
2020/07/29 Javascript
python元组操作实例解析
2014/09/23 Python
python卸载后再次安装遇到的问题解决
2019/07/10 Python
python rsync服务器之间文件夹同步脚本
2019/08/29 Python
django中瀑布流写法实例代码
2019/10/14 Python
jupyter notebook 添加kernel permission denied的操作
2020/04/21 Python
matplotlib设置颜色、标记、线条,让你的图像更加丰富(推荐)
2020/09/25 Python
Django restful framework生成API文档过程详解
2020/11/12 Python
Python 利用Entrez库筛选下载PubMed文献摘要的示例
2020/11/24 Python
python 如何用urllib与服务端交互(发送和接收数据)
2021/03/04 Python
纯css3(无图片/js)制作的几个社交媒体网站的图标
2013/03/21 HTML / CSS
纯css实现照片墙3D效果的示例代码
2017/11/13 HTML / CSS
html5手机键盘弹出收起的处理
2020/01/20 HTML / CSS
写出程序把一个链表中的接点顺序倒排
2014/04/28 面试题
《与象共舞》教学反思
2014/02/24 职场文书
导游词开场白
2015/01/31 职场文书
《金钱的魔力》教学反思
2016/02/20 职场文书
MySQL Router的安装部署
2021/04/24 MySQL