Sinon: рдПрдХ рд╕реНрдЯреИрдВрдбрдЕрд▓реЛрди рдЙрдкрдпреЛрдЧрд┐рддрд╛ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд░реЛрдХрдирд╛ рд╕рдВрднрд╡ рд╣реИ?

рдХреЛ рдирд┐рд░реНрдорд┐рдд 12 рд╕рд┐рддре░ 2014  ┬╖  18рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: sinonjs/sinon

рдХрдИ рдиреЛрдб рдореЙрдбреНрдпреВрд▓ рдЕрдкрдиреЗ "module.exports" рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рдПрдХрд▓ рдлрд╝рдВрдХреНрд╢рди (рдПрдХ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдлрд╝рдВрдХреНрд╢рди рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдЙрджреНрджреЗрд╢реНрдп "рдЙрдкрдпреЛрдЧрд┐рддрд╛" рдлрд╝рдВрдХреНрд╢рди) рдХреЛ рдирд┐рд░реНрдпрд╛рдд рдХрд░рддреЗ рд╣реИрдВред рдХреНрдпрд╛ рдЗрд╕ рд╕реНрдЯреИрдВрдбрдЕрд▓реЛрди рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП Sinon.js рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ?

// some module, "sum.js" that's "required" throughout the application
module.exports = function(a, b) {
    return a + b;
};

// test.js
var sum = require('sum');
...

beforeEach(function() {
    sumStub = sinon.stub(sum);
    // throws: TypeError: Attempted to wrap undefined property undefined as function
});

afterEach(function() {
   sumStub.restore();
});
...

рдХреНрдпрд╛ рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рддрд░реАрдХрд╛ рд╣реИ?

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

рдпреЗ рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВ

import * as sum from './sum'
sinon.stub(sum, 'default', () => {
  // stubbed function
});

рд╕рднреА 18 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ рдирд╣реАрдВред

рдПрдирдкреАрдПрдо рдХреЗ рд▓рд┐рдП рдЖрдк https://github.com/thlorenz/proxyquire рдпрд╛ рдЗрд╕реА рддрд░рд╣ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдорд╛рдЗрдХрд▓ рдлреЗрджрд░реНрд╕ рдЗрд╕реЗ рдПрдХ рд▓рд┐рдВрдХ рд╕реАрдо рдХрд╣реЗрдВрдЧреЗред

рдпрд╣ рд╕реБрд░реБрдЪрд┐рдкреВрд░реНрдг рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╣реИред

рдПрдХ рдмрд╛рд░ рдЖрдкрдХреЗ рдкрд╛рд╕ рд╡рд╣ рдЬрдЧрд╣ рд╣реЛ рдЬрд╛рдиреЗ рдХреЗ рдмрд╛рдж, рдЖрдк рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рд╕рд┐рдиреЙрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рд▓рдВрдмреЗ рд╕рдордп рдореЗрдВ, рдЖрдк рдЕрдкрдиреЗ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХреЛ _рдСрдмреНрдЬреЗрдХреНрдЯ рд╕реАрдо_ рдХреА рдУрд░ рд▓реЗ рдЬрд╛рдирд╛ рдЪрд╛рд╣ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдПрдХ рдРрд╕рд╛ рд╕рдорд╛рдзрд╛рди рд╣реИ рдЬреЛ рдЖрдЬ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред RequJS рдХреЗ рд▓рд┐рдП рдЗрд╕реА рддрд░рд╣ рдХреА рдкрд░рд┐рдпреЛрдЬрдирд╛рдПрдВ рдореМрдЬреВрдж рд╣реИрдВред

function MyFunction(){}
module.exports = function(){ return module.exports.MyFunction.apply(this, arguments) }
module.exports.MyFunction = MyFunction

рдлрд┐рд░ рдЖрдк рдЖрд╡рд╢реНрдпрдХрддрд╛ ('./MyFunction') рдХреЛ рд╕реНрдЯрдм рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред MyFunction рдФрд░ рдЖрдкрдХрд╛ рдмрд╛рдХреА рдХреЛрдб рдмрд┐рдирд╛ рдмрджрд▓рд╛рд╡ рдХреЗ рд╕реНрдЯрдмреНрдб рд╕рдВрд╕реНрдХрд░рдг рджреЗрдЦреЗрдЧрд╛ред

:рдЪрдХреНрдХрд░ рдЖрдирд╛: :dizzy_face: :dizzy:

рджреВрд╕рд░реЗ рджрд┐рди рдЙрд╕реА рдЪреАрдЬрд╝ рдореЗрдВ рдареЛрдХрд░ рдЦрд╛рдИ, рдпрд╣рд╛рдБ рдореИрдВрдиреЗ рдХреНрдпрд╛ рдХрд┐рдпрд╛:

const proxyquire = require('proxyquire')
const sinon = require('sinon')
const sum = sinon.stub()

const ModuleWithDependency = proxyquire('module', {
  'sum': sum
})

рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

рдпрджрд┐ рдХреЙрдордирдЬреЗрдПрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВ:

const myStubbedModule = function( absoluteModulePath ) {
  const stub = sinon.stub();
  require.cache[ require.resolve( absoluteModulePath ) ] = stub;
  return stub;
}

_рдиреЛрдЯ_: рдЖрдк рдЯреНрд░рд╛рдВрд╕рдкрд┐рд▓рд┐рдВрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдпрд╛ рдирд╣реАрдВ, рдЗрд╕рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдЖрдкрдХреЛ рдпрд╣ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИ:

require.cache[ require.resolve( absoluteModulePath ) ] = {
  default: stub,
  exports: stub
}

рдЕрдХреНрд╕рд░ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рджреМрд░рд╛рди рдореБрдЭреЗ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдПрдХ рдареВрдВрда рдбрд╛рд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рдореЗрд░реЗ рджреНрд╡рд╛рд░рд╛ рд▓рд┐рдпрд╛ рдЧрдпрд╛ рд░реИрдкрд░-рдлрд╝рдВрдХреНрд╢рди рджреГрд╖реНрдЯрд┐рдХреЛрдг рдореБрдЭреЗ рдХреЛрдбрдмреЗрд╕ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдиреЗ рдФрд░ рдЬрдм рднреА рдореИрдВ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ, рдореЗрд░реЗ рд╕реНрдЯрдмреНрд╕ рдбрд╛рд▓рдиреЗ рджреЗрддрд╛ рд╣реИ, рдмрд┐рдирд╛ рд╕реНрдЯрдм-рдлрд░реНрд╕реНрдЯ рдЕрдкреНрд░реЛрдЪ рдпрд╛ рд╡реНрд╣реЗрдХ-рдП-рдореЛрд▓ рдЦреЗрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдореЙрдбреНрдпреВрд▓ рдХреЗ рд╕рд╛рде рдЕрдиреНрдп рдореЙрдбреНрдпреВрд▓ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдореИрдВ рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдареВрдВрда рдФрд░ рдЬрдЧрд╣-рдЬрдЧрд╣ред

рдореЗрд░реЗ рдкрд╛рд╕ рдХрдИ рдХреЛрдб рд╕рдореАрдХреНрд╖рд╛рдПрдВ рд╣реИрдВ рдЬрд╣рд╛рдВ рд▓реЛрдЧреЛрдВ рдиреЗ рдореБрдЭреЗ рдкреНрд░реЙрдХреНрд╕реАрдХреНрд╡рд╛рдпрд░, рдореЙрдХ-рдЖрд╡рд╢реНрдпрдХрддрд╛ , рдФрд░ рд╕реА рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдиреЛрдб рдореЙрдбреНрдпреВрд▓ рдкрд░рдд рдкрд░ рд╣реИрдХрд┐рдВрдЧ рдХреА рдУрд░ рдзрдХреЗрд▓ рджрд┐рдпрд╛ рд╣реИ, рдФрд░ рдпрд╣ рд╕рд░рд▓ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдХрдо рдХреНрд░реВрд░ рд▓рдЧрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╕реНрдЯрдмреНрд╕ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдПрдХ рдмрд╣реБрдд рд╣реА рдХрдард┐рди рдЪреБрдиреМрддреА рдмрди рдЬрд╛рддреА рд╣реИ рдкрд░реАрдХреНрд╖рдг рд╕реЗрдЯрдЕрдк рдХреЗ рджреМрд░рд╛рди рдЬрдЧрд╣ рдХреА рдЬрд░реВрд░рдд рд╣реИред рдкреНрд░реЙрдХреНрд╕реАрдХреНрд╡рд╛рдпрд░ рдХреЗ рд╕рд╛рде рдХрдо рд╕реЗ рдХрдо рдХреЛрдИ рдРрдк рдХрд╛ рдПрдХ рдорд╛рдЗрдХреНрд░реЛ-/рдлрд┐рдХреНрд╕реНрдЪрд░-рдЖрдХрд╛рд░ рдХрд╛ рд╕рдВрд╕реНрдХрд░рдг рдкреНрд░реЙрдХреНрд╕реАрдХреНрд╡рд╛рдпрд░ () рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдХреБрдЫ рд╢реАрд░реНрд╖ рд╕реНрддрд░, рдФрд░ рдЗрд╕рдХреЗ рд▓реЛрдб рдХреЗ рджреМрд░рд╛рди рд╕рднреА рд╕реНрдЯрдмреНрд╕ рд▓рд╛рдП рдЬрд╛рдПрдВрдЧреЗ, рд▓реЗрдХрд┐рди рдиреЛрдб рдореЙрдбреНрдпреВрд▓ рд╕реНрддрд░ рдХреЗ рдмрдЬрд╛рдп рдЬреЗрдПрд╕ рднрд╛рд╖рд╛ рд╕реНрддрд░ рдкрд░ рдЗрд╕рд╕реЗ рдирд┐рдкрдЯрдирд╛ рдЬрд╛рд░реА рд╣реИ рдореБрдЭреЗ рдФрд░ рдЕрдзрд┐рдХ рд╕рд░рд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдФрд░ рд▓рдЧрд╛рддрд╛рд░ рдФрд░ рдмрд┐рдирд╛ рдХрд┐рд╕реА рдЦрддрд░реЗ рдХреЗ рдкреНрд░рдмрдВрдзрди рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИ (рдЪреЗрддрд╛рд╡рдиреА: рдЬрдм рддрдХ рдХреЛрдИ рдкреБрдирд░реНрд╕реНрдерд╛рдкрд┐рдд рдХрд░рдирд╛ рдпрд╛рдж рд░рдЦрддрд╛ рд╣реИ)ред

рдореИрдВрдиреЗ рдЗрд╕ рдореЙрдбреНрдпреВрд▓ рдХреЛ рдЕрдзрд┐рдХ рдЖрд╕рд╛рдиреА рд╕реЗ рд╕реНрдЯрдм рдореЙрдбреНрдпреВрд▓ рдХреЗ рд▓рд┐рдП рдмрдирд╛рдпрд╛ рд╣реИ https://github.com/caiogondim/stubbable-decorator.js

рдореИрдВ рд╕рд┐рд░реНрдл рд╕рд┐рдиреЙрди рдХреЗ рд╕рд╛рде рдЦреЗрд▓ рд░рд╣рд╛ рдерд╛ рдФрд░ рд╕рд░рд▓ рд╕рдорд╛рдзрд╛рди рдорд┐рд▓рд╛ рдЬреЛ рдХрд╛рдо рдХрд░рддрд╛ рдкреНрд░рддреАрдд рд╣реЛрддрд╛ рд╣реИ - рдмрд╕ рджреВрд╕рд░реЗ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ 'рддрд░реНрдХ' рдЬреЛрдбрд╝реЗрдВ

const sumStub = sinon.stub(sum, 'arguments');
sumStub.withArgs(2, 2).returns(4);
sumStub.withArgs(3, 3).returns(6);

рдпреЗ рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВ

import * as sum from './sum'
sinon.stub(sum, 'default', () => {
  // stubbed function
});

@ harryi3t - рдзрдиреНрдпрд╡рд╛рдж рдХрд┐ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдХрд┐рдпрд╛ред

@ harryi3t ES рдореЙрдбреНрдпреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдирд╣реАрдВ рдХрд┐рдпрд╛ред
рддреНрд░реБрдЯрд┐: can't redefine non-configurable property "default"

@elliottregan ES рдореЙрдбреНрдпреВрд▓ рдорд╛рдирдХ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдареВрдВрдарджрд╛рд░ рдирд╣реАрдВ рд╣реИрдВред рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЗрд╕ рд╡реНрдпрд╡рд╣рд╛рд░ рдореИрдВ рдпрд╣рд╛рдБ рдЪрд░реНрдЪрд╛ рдХрд░ рд░рд╣рд╛ рд╣реВрдБ , рдЖрдк рдЗрд╕реЗ рдЕрднреА рднреА рдХрд░ рд╕рдХрддреЗ

рдмрд╣реБрдд рд╕реЗ рд▓реЛрдЧ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ ES рдореЙрдбреНрдпреВрд▓ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди ES рдореЙрдбреНрдпреВрд▓ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ (рд╡реЗрдмрдкреИрдХ/рдмреЗрдмреЗрд▓, рдЖрджрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ)ред рдкрд░рд┐рдгрд╛рдореА ES5 ES рдореЙрдбреНрдпреВрд▓ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рдХрд╛ рдЕрдиреБрдХрд░рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЧреЗрдЯрд░реНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдЖрдк рдРрд╕рд╛ рдХрд░ рд░рд╣реЗ рд╣реЛрдВ, рд▓реЗрдХрд┐рди рд▓рд┐рдВрдХ рдХрд┐рдП рдЧрдП рдзрд╛рдЧреЗ рдореЗрдВ рдореЗрд░реЗ рджреНрд╡рд╛рд░рд╛ рд╕реБрдЭрд╛рдП рдЧрдП рд╕рд░рд▓ рдорд╛рд░реНрдЧ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред mocha --register ... рдЖрдкрдХреЛ рдмрд╣реБрдд рдЖрдЧреЗ рд▓реЗ рдЬрд╛рддрд╛ рд╣реИред

рд╕рдВрднрд╛рд╡рд┐рдд рд╕рдорд╛рдзрд╛рди

(function (defineProperty) {
    Object.defineProperty = (obj, prop, desc) => {
        desc.configurable = true;
        return defineProperty(obj, prop, desc);
    };
})(Object.defineProperty);

@ рд╕реБрдЬреАрдореЛрд╢реА рд╡рд░реНрдХрдЕрд░рд╛рдЙрдВрдб рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХрд┐рд╕ рд▓рд┐рдП? рдЖрдкрдХреЗ рдлрд┐рдХреНрд╕ рдХреЗ рд▓рд┐рдП рд╕рдВрджрд░реНрдн рдХреНрдпрд╛ рд╣реИ? рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд▓реЛрдЧ рдлрд┐рдХреНрд╕ рдХрд╣рд╛рдВ рд░рдЦреЗрдВрдЧреЗ? рдЕрдкрдиреЗ рд╡рд░реНрддрдорд╛рди рдЕрд╡рддрд╛рд░ рдореЗрдВ, рд╕рд╣рд╛рдпрдХ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕рдореЗрдВ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдирд╣реАрдВ рд╣реИред рдпрд╣ рдореВрд▓ рдкреНрд░рд╢реНрди рдореЗрдВ рдорджрдж рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ рдФрд░ ES рдореЙрдбреНрдпреВрд▓ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред рдореИрдВ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛ рд░рд╣рд╛ рд╣реВрдВ рдХрд┐ рдпрд╣ рдЙрд╕ рдХреЛрдб рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИ рдЬрд┐рд╕реЗ рд╡реЗрдмрдкреИрдХ 4 рджреНрд╡рд╛рд░рд╛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ ES2015+ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓рд┐рдЦреЗ рдЧрдП рдХреЛрдб рдкрд░ рд▓рд╛рдЧреВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ (рдЖрдкрдХреЗ рдЯреВрд▓рдЪреИрди рдХреЗ рдЖрдзрд╛рд░ рдкрд░) рдЬреЛ ES5 рдореЗрдВ _transpiled_, _emulatory_ рдЧреИрд░-рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдСрдмреНрдЬреЗрдХреНрдЯ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ ES рдореЙрдбреНрдпреВрд▓ рдХреА рдЕрдкрд░рд┐рд╡рд░реНрддрдиреАрдпрддрд╛ рд╣реИред .

рдпреЗ рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВ

import * as sum from './sum'
sinon.stub(sum, 'default', () => {
  // stubbed function
});

рдЕрдм рдмрд╣рд┐рд╖реНрдХреГрддред

рдореИрдВрдиреЗ рдЗрд╕рд╕реЗ рдЕрдкрдирд╛ ES6 рдореЙрдбреНрдпреВрд▓ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрд╛:

export default const doCoolStuff = () => {
  // do the cool stuff...
}

рдЗрд╕рдХреЗ рд▓рд┐рдП:

export default {
  doCoolStuff: () => {
    // do the cool stuff...
  }
} 

рдпрд╣ рдереЛрдбрд╝рд╛ рдХреНрд▓рдВрдХреА рд╣реИ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╕реНрдЯрдм рдореЗрдВ рд▓рдкреЗрдЯрдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдмрдирд╛рддрд╛ рд╣реИред

рдЕрдм рд▓рдЧрднрдЧ 2021 рд╣реИ, рдХреНрдпрд╛ рдпрд╣ рд╕рдВрднрд╡ рд╣реИ?

рдЕрдм рд▓рдЧрднрдЧ 2021 рд╣реИ, рдХреНрдпрд╛ рдпрд╣ рд╕рдВрднрд╡ рд╣реИ?

2019 рд╕реЗ рдмрд╣реБрдд рдЕрд▓рдЧ рдирд╣реАрдВ рд╣реИред
ES рдореЙрдбреНрдпреВрд▓ рдирд╣реАрдВ рдмрджрд▓рд╛ рд╣реИ, CommonJS рдирд╣реАрдВ рдмрджрд▓рд╛ рд╣реИ, рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдирд╣реАрдВ рдмрджрд▓рд╛ рд╣реИред

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

ndhoule picture ndhoule  ┬╖  4рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

fearphage picture fearphage  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

brettz9 picture brettz9  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

andys8 picture andys8  ┬╖  4рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

stephanwlee picture stephanwlee  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ