使用包時,報 xxx.default is not a function

 最近作了一個導出功能,代碼以下
import request from 'request-promise-native';
 export default class Form {
  // 導出
  @post('/export')
  public async export(ctx) {
    const params = JSON.parse(ctx.request.body.fields.params);
    const dataExport = await request({
      method: 'POST',
      uri: utils.url.org(ctx, '/v1/:route'),
      json: true,
      headers: {
        cookie: ctx.request.header.cookie,
      },
      qs: params.exportParam, 
    });
    await excel.export(ctx, params.tableName, params.column, dataExport.items);
  }
 }

報錯
request_promise_native_1.default is not a function

解決方法:引入方式改成
import * as request from 'request-promise-native';

 

首先咱們要明白一個前提,CommonJS模塊規範和ES6模塊規範徹底是兩種不一樣的概念。

看一下下面的 CommonJs module 和 ES6的module ,就能夠懂了

CommonJS規範

Module 的語法

 

打印引入的request  查看不一樣的引入方式 request 值有什麼區別javascript

----1-------------------------------------------
request-promise-native包的導出方式是:module.exports = request;
不一樣引入方式,打印結果: 1. import * as request from 'request-promise-native';   打印request ,結果以下:   function request(uri, options, callback) {     if (typeof uri === 'undefined') {       throw new Error('undefined is not a valid uri or options object.')     }     var params = initParams(uri, options, callback)     if (params.method === 'HEAD' && paramsHaveRequestBody(params)) {       throw new Error('HTTP HEAD requests MUST NOT include a request body.')     }     return new request.Request(params)   } 2. import request from 'request-promise-native';   打印 request 結果是 undefined
3. import {request} from 'request-promise-native';
  打印 request 結果是 undefined
 ----2------------------------------------------- 
若是
request-promise-native 包導出方式改成以下方式:
包導出: module.exports.request = request; 等同於 module.exports = {request}; 不一樣引入方式,打印結果: 1. import * as request from 'request-promise-native';   打印request ,結果以下:   { request:
    { [Function: request]
    get: [Function],  head: [Function],  options: [Function],
    post: [Function],  put: [Function],  patch: [Function],  del: [Function],  delete: [Function],
    jar: [Function],  cookie: [Function],  defaults: [Function],  forever: [Function],
    Request: { [Function: Request] super_: [Object], debug: undefined, defaultProxyHeaderWhiteList: [Array], defaultProxyHeaderExclusiveList: [Array] },
    initParams: [Function: initParams],
    debug: [Getter/Setter] } 
  }
2. import request from 'request-promise-native';
  打印 request 結果是 undefined
3. import {request} from 'request-promise-native';
  打印 request 結果以下:
  function request(uri, options, callback) {
    if (typeof uri === 'undefined') {
      throw new Error('undefined is not a valid uri or options object.')
    }
    var params = initParams(uri, options, callback)
    if (params.method === 'HEAD' && paramsHaveRequestBody(params)) {
      throw new Error('HTTP HEAD requests MUST NOT include a request body.')
    }
    return new request.Request(params)
  }
----3-------------------------------------------
若是 request-promise-native 包導出方式改成以下方式:
包導出: module.exports.default = request;
不一樣引入方式,打印結果:
1. import * as request from 'request-promise-native';
  打印request ,結果以下:
  { default: 
    { [Function: request]
    get: [Function],  head: [Function],  options: [Function],
    post: [Function],  put: [Function],  patch: [Function],  del: [Function],  delete: [Function],
    jar: [Function],  cookie: [Function],  defaults: [Function],  forever: [Function],
    Request: { [Function: Request] super_: [Object], debug: undefined, defaultProxyHeaderWhiteList: [Array], defaultProxyHeaderExclusiveList: [Array] },
    initParams: [Function: initParams],
    debug: [Getter/Setter] } 
  } 2. import request from 'request-promise-native';   打印 request 結果以下:
  function request(uri, options, callback) {
    if (typeof uri === 'undefined') {
      throw new Error('undefined is not a valid uri or options object.')
    }
    var params = initParams(uri, options, callback)
    if (params.method === 'HEAD' && paramsHaveRequestBody(params)) {
      throw new Error('HTTP HEAD requests MUST NOT include a request body.')
    }
    return new request.Request(params)
  }
3. import {request} from 'request-promise-native';
  打印 request  結果是 undefined


-----總結----------------------------------------
導出:( = 右側的 request 是一個function,從源碼中得知)
out1: module.exports = request;  // 導出的是 function
out2: module.exports.request = request; // 導出的是對象 {request:function}
out3: module.exports.default = request; // 導出的是對象 {default:function}

引入:
in1: import * as request from 'request-promise-native'; // * as request => out1: request = function; out2: request = {request:function}; out3: request = {default:function} => 導出的內容 = request
in2: import {request} from 'request-promise-native'; // request => out1: request = undefined; out2: request = function; out3: request = undefined => 解構賦值 
in3: import request from 'request-promise-native'; // {request} => out1: request = undefined; out2: request = undefined; out3: request = function => module.exports.default = 隨意命名
 

  查看不一樣引入方式的編譯結果:html

-----不一樣引入方式,打包編譯結果-----------------------java

request-promise-native 源碼:node

-------1-- module.exports = request -------------------------react

request-promise-native 源碼:最後一句導出 module.exports = request
左邊 引入: import request from 'request-promise-native';
右邊 引入: import * as request from 'request-promise-native'; 
打包後的結果是:

左側引入方式 import request from 'request-promise-native';es6

程序報錯: request_promise_native_1.default is not a functiontypescript

若是引入方式改成 :import {request} from 'request-promise-native';json

程序報錯: request_promise_native_1.request is not a functionpromise

 -------2-----module.exports.default = request----------------------cookie

request-promise-native 源碼:最後一句導出  若改爲 module.exports.default = request;

左邊 引入: import request from 'request-promise-native';
右邊 引入: import * as request from 'request-promise-native'; 
左右兩邊編譯後同樣 request_promise_native_1.default 就是 request 因此不報錯
打包後的結果是:


 -------3------module.exports = {request}---------------------

request-promise-native 源碼:最後一句導出  若改爲 module.exports = {request};

左邊 引入: import request from 'request-promise-native';
右邊 引入: import * as request from 'request-promise-native'; 
以上兩種方式引入,均報錯
若引入方式改成:import {request} from 'request-promise-native';
則不報錯, 導出成功
 
-----總結----------------------------------------
判斷引入包A是否有default
in1: import * as A1 from A // 沒有default: A1 = require(A) 使用:A1() ; 有default: A1_xx= = require(A) 使用: A1_xx.default()
in2: import A1 from A // 無論有沒有default: A1_xx= = require(A) 使用: A1_xx. default ()
in3: import {A1} from A // 無論有沒有default: A1_xx= = require(A) 使用: A1_xx. A1 ()
 
import包的方式,由包的exports內容決定
 ----------------------------------------------------------------------------------
 
 
  

 

 -------4---------------------------

request-promise-native 源碼:最後一句導出

module.exports = request;
若改爲
export default request;

可是程序仍報錯  SyntaxError: Unexpected token export

打包編譯結果以下:左邊import 右邊 import * as , 結果是好的
 
 
   

 
如今咱們使用 react, typescript
都會使用es6語法,建立class
使用以下方式導出 
export default class Form
export default new class {}
-----------------------------
typescript的.ts文件經過 tsc 命令打包 編譯結果是 
exports["default"] = new /** @class */ (function () {...}
因此直接 import 

-----------------------------  

相關文章
相關標籤/搜索