使用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 相关文章推荐
各浏览器中querySelector和querySelectorAll的实现差异分析
May 23 Javascript
表单元素的submit()方法和onsubmit事件应用概述
Feb 01 Javascript
jquery uploadify 在FF下无效的解决办法
Sep 26 Javascript
基于javascript实现的搜索时自动提示功能
Dec 26 Javascript
javascript感应鼠标图片透明度显示的方法
Feb 24 Javascript
JavaScript_ECMA5数组新特性详解
Jun 12 Javascript
js 获取站点应用名的简单实例
Aug 18 Javascript
Angularjs 设置全局变量的方法总结
Oct 20 Javascript
JavaScript实现的原生态兼容IE6可调可控滚动文字功能详解
Sep 19 Javascript
Angular数据绑定机制原理
Apr 17 Javascript
JS实现省市县三级下拉联动
Apr 10 Javascript
JavaScript实现消消乐的源代码
Jan 12 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注释实例技巧
2008/10/03 PHP
php中使用addslashes函数报错问题的解决方法
2013/02/06 PHP
PHP生成不同颜色、不同大小的tag标签函数
2013/09/23 PHP
PHP之正则表达式捕获组与非捕获组(详解)
2015/07/29 PHP
php获取文件名称和扩展名的方法
2017/02/07 PHP
基于PHP常用文件函数和目录函数整理
2017/08/17 PHP
快速解决PHP调用Word组件DCOM权限的问题
2017/12/27 PHP
如何在PHP中使用AES加密算法加密数据
2020/06/24 PHP
JS 时间显示效果代码
2009/08/23 Javascript
jquery.validate使用攻略 第一部
2010/07/01 Javascript
JavaScript 错误处理与调试经验总结
2010/08/10 Javascript
jQuery Mobile的loading对话框显示/隐藏方法分享
2013/11/26 Javascript
JavaScript给url网址进行encode编码的方法
2015/03/18 Javascript
浅谈javascript中onbeforeunload与onunload事件
2015/12/10 Javascript
JS实现Select的option上下移动的方法
2016/03/01 Javascript
最简单的tab切换实例代码
2016/05/13 Javascript
Vue.js 表单校验插件
2016/08/14 Javascript
AngularJS实现单独作用域内的数据操作
2016/09/05 Javascript
详解jQuery停止动画——stop()方法的使用
2016/12/14 Javascript
在Vue组件中使用 TypeScript的方法
2018/02/28 Javascript
Vue页面骨架屏的实现方法
2018/05/22 Javascript
vue+echarts实现可拖动节点的折线图(支持拖动方向和上下限的设置)
2019/04/12 Javascript
JS查找孩子节点简单示例
2019/07/25 Javascript
帮你彻底搞懂JS中的prototype、__proto__与constructor(图解)
2019/08/23 Javascript
python用户评论标签匹配的解决方法
2018/05/31 Python
python numpy 按行归一化的实例
2019/01/21 Python
Python如何使用PIL Image制作GIF图片
2020/05/16 Python
鼠标滚轮事件和Mac触控板双指事件
2019/12/23 HTML / CSS
Hotels.com台湾:饭店订房网
2017/09/06 全球购物
前厅收银主管岗位职责
2014/02/04 职场文书
小学生自我评价100字(15篇)
2014/09/18 职场文书
小班下学期幼儿评语
2014/12/30 职场文书
2015年医院工作总结范文
2015/04/09 职场文书
2015年入党积极分子培养考察意见
2015/08/12 职场文书
高中政治教师教学反思
2016/02/23 职场文书
德劲DE1105机评
2022/04/05 无线电