• koa 项目打包(使用webpack打包koa2 框架app)


    关键问题

    一:所有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部署上线就好了。然后在服务器上执行

    npm install 
    npm run for
    

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

    .

  • 相关阅读:
    [译]Node.js Interview Questions and Answers (2017 Edition)
    XUnit
    Inline Route Constraints in ASP.NET Core MVC
    [译]Object.getPrototypeOf
    [译]IIS 8.0应用初始化
    C++的那些事:你真的了解引用吗
    C++的那些事:表达式与语句
    C++的那些事:数据与类型
    神经网络:卷积神经网络
    图像分析:投影曲线的波峰查找
  • 原文地址:https://www.cnblogs.com/crazycode2/p/11192251.html
Copyright © 2020-2023  润新知