使用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 相关文章推荐
JS获得浏览器版本和操作系统版本的例子
May 13 Javascript
javascript中JSON.parse()与eval()解析json的区别
May 19 Javascript
微信小程序 wxapp视图容器 view详解
Oct 31 Javascript
Bootstrap的class样式小结
Dec 01 Javascript
浅谈js键盘事件全面控制
Dec 01 Javascript
详解jQuery中的DOM操作
Dec 23 Javascript
Vue filter介绍及其使用详解
Oct 21 Javascript
vue2.0 父组件给子组件传递数据的方法
Jan 15 Javascript
vue webpack打包优化操作技巧
Feb 22 Javascript
vuex state中的数组变化监听实例
Nov 06 Javascript
vant实现购物车功能
Jun 29 Javascript
基于JavaScript实现随机点名器
Feb 25 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
用PHP调用数据库的存贮过程
2006/10/09 PHP
用libTemplate实现静态网页的生成
2006/10/09 PHP
php目录管理函数小结
2008/09/10 PHP
php类中的$this,static,final,const,self这几个关键字使用方法
2015/12/14 PHP
php格式文件打开的四种方法
2018/02/24 PHP
PHP htmlspecialchars()函数用法与实例讲解
2019/03/08 PHP
thinkphp整合系列之极验滑动验证码geetest功能
2019/06/18 PHP
Jquery 高亮显示文本中重要的关键字
2009/12/24 Javascript
JavaScript 代码压缩工具小结
2012/02/27 Javascript
输入密码检测大写是否锁定js实现代码
2012/12/03 Javascript
Jquery仿IGoogle实现可拖动窗口示例代码
2014/08/22 Javascript
谈谈js中的prototype及prototype属性解释和常用方法
2015/11/25 Javascript
jQuery实例—选项卡的简单实现(js源码和jQuery)
2016/06/14 Javascript
js删除数组元素、清空数组的简单方法(必看)
2016/07/27 Javascript
seajs模块之间依赖的加载以及模块的执行
2016/10/21 Javascript
如何在 Vue.js 中使用第三方js库
2017/04/25 Javascript
vue 注册组件的使用详解
2018/05/05 Javascript
小程序实现短信登录倒计时
2019/07/12 Javascript
详解element-ui中el-select的默认选择项问题
2019/08/02 Javascript
React学习之JSX与react事件实例分析
2020/01/06 Javascript
vue-router定义元信息meta操作
2020/12/07 Vue.js
Python Deque 模块使用详解
2014/07/04 Python
python版简单工厂模式
2017/10/16 Python
Python 数据处理库 pandas进阶教程
2018/04/21 Python
python2与python3的print及字符串格式化小结
2018/11/30 Python
python3正则提取字符串里的中文实例
2019/01/31 Python
Python数据报表之Excel操作模块用法分析
2019/03/11 Python
python接口自动化如何封装获取常量的类
2019/12/24 Python
文字自荐书范文
2014/02/10 职场文书
《美丽的小兴安岭》教学反思
2014/02/26 职场文书
推广普通话标语
2014/06/27 职场文书
安全生产隐患排查制度
2015/08/05 职场文书
经典人生语录分享:不畏将来,不念过去,笑对当下
2019/12/12 职场文书
SpringBoot中HttpSessionListener的简单使用方式
2022/03/17 Java/Android
剑指Offer之Java算法习题精讲二叉树的构造和遍历
2022/03/21 Java/Android
SpringCloud中分析讲解Feign组件添加请求头有哪些坑梳理
2022/06/21 Java/Android