使用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 相关文章推荐
jQuery实现查找最近父节点的方法
Jun 23 Javascript
js实现弹窗暗层效果
Jan 16 Javascript
jQuery Pagination分页插件使用方法详解
Feb 28 Javascript
JavaScript设计模式之策略模式详解
Jun 09 Javascript
微信禁止下拉查看URL的处理方法
Sep 28 Javascript
vue-cli开发时,关于ajax跨域的解决方法(推荐)
Feb 03 Javascript
浅谈React之状态(State)
Sep 19 Javascript
vue.js 2.*项目环境搭建、运行、打包发布的详细步骤
May 01 Javascript
详解Vue中组件传值的多重实现方式
Aug 16 Javascript
在VUE style中使用data中的变量的方法
Jun 19 Javascript
mapboxgl区划标签避让不遮盖实现的代码详解
Jul 01 Javascript
vue-treeselect的基本用法以及解决点击无法出现拉下菜单
Apr 30 Vue.js
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
实战mysql导出中文乱码及phpmyadmin导入中文乱码的解决方法
2010/06/11 PHP
php5.2 Json不能正确处理中文、GB编码的解决方法
2014/03/28 PHP
WordPres对前端页面调试时的两个PHP函数使用小技巧
2015/12/22 PHP
php删除数组指定元素实现代码
2017/05/03 PHP
thinkPHP5框架路由常用知识点汇总
2019/09/15 PHP
Javascript 原型和继承(Prototypes and Inheritance)
2009/04/01 Javascript
用jquery ajax获取网站Alexa排名的代码
2009/12/12 Javascript
Javascript中的isNaN函数使用说明
2011/11/10 Javascript
js计算字符串长度包含的中文是utf8格式
2013/10/15 Javascript
jquery+html5制作超酷的圆盘时钟表
2015/04/14 Javascript
Javascript页面跳转常见实现方式汇总
2015/11/28 Javascript
JS动态加载脚本并执行回调操作
2016/08/24 Javascript
Nodejs下DNS缓存问题浅析
2016/11/16 NodeJs
微信公众号菜单配置微信小程序实例详解
2017/03/31 Javascript
微信小程序实现图片上传功能
2018/05/28 Javascript
IE11下处理Promise及Vue的单项数据流问题
2019/07/24 Javascript
layer实现登录弹框,登录成功后关闭弹框并调用父窗口的例子
2019/09/11 Javascript
JavaScript实现动态生成表格
2020/08/02 Javascript
Vue3配置axios跨域实现过程解析
2020/11/25 Vue.js
python使用opencv读取图片的实例
2017/08/17 Python
详谈在flask中使用jsonify和json.dumps的区别
2018/03/26 Python
python tkinter图形界面代码统计工具
2019/09/18 Python
Python图片的横坐标汉字实例
2019/12/04 Python
tensorflow查看ckpt各节点名称实例
2020/01/21 Python
Python 为什么推荐蛇形命名法原因浅析
2020/06/18 Python
python hmac模块验证客户端的合法性
2020/11/07 Python
为有想象力的人提供的生活方式商店:Firebox
2018/06/04 全球购物
兰蔻英国官网:Lancome英国
2019/04/30 全球购物
自荐信结尾
2013/10/27 职场文书
电子商务应届生自我鉴定
2014/01/13 职场文书
和谐家庭演讲稿
2014/05/24 职场文书
高中学校对照检查材料
2014/08/31 职场文书
2014年合同管理工作总结
2014/12/02 职场文书
2015年度绩效考核工作总结
2015/05/27 职场文书
python如何在word中存储本地图片
2021/04/07 Python
Python中Cookies导出某站用户数据的方法
2021/05/17 Python