Javascript-форум (https://javascript.ru/forum/)
-   Сборка проекта, утилиты (https://javascript.ru/forum/server-tools/)
-   -   webpack, es6-модули, default и все дела (https://javascript.ru/forum/server-tools/60380-webpack-es6-moduli-default-i-vse-dela.html)

vasa_c 25.12.2015 15:30

webpack, es6-модули, default и все дела
 
Пишу, значит, на TypeScript NPM-пакет и использую es6-модули:

Код:

export default function sqr(a: number): number {
    return a * a;
}

ES-6 модулей нигде в живую нет, так что TypeScript, как и Babel гоняет экспорт через объект, где для дефолтного экспорта используется поле default:

function sqr(a) {
    return a * a;
}
exports["default"] = sqr;


Задно я хочу чтобы эту библиотеку можно было по старинке подключить в браузере. Собираю через webpack, с указанием глобальной переменной.
Конфиг вебпака:

module.exports = {
    context: __dirname,
    entry: "./index.js",
    output: {
        path: __dirname,
        filename: "browser-version.js",
        library: "mySqr"
    }
};


Собирается это в следующий код:

var mySqr =
    (function(modules) { // webpackBootstrap
    
    // ...
    
    ([
    function(module, exports) {

	function sqr(a) {
	    return a * a;
	}
	exports["default"] = sqr;

/***/ }
/******/ ]);



То есть в браузере у нас теперь доступна переменная mySqr. Вот только из-за манипуляций с es6-модулями в этой переменной не сама исходная функция, а объект {default: sqr}.

Можно ли как-то указать webpack'у, чтобы он обрабатывал такие ситуации. Либо более общий случай - указать поле которое следует импортировать из модуля, вместо модуля целиком.

В зарубежных интернетах нашёл десяток похожих тем, но нигде нет решения. Может быть они чего-то не знают?

nerv_ 26.12.2015 10:41

https://github.com/nervgh/recursive-...untfile.js#L47

vasa_c 26.12.2015 16:22

nerv_, не совсем понял.
Предлагаете использовать libraryTarget: umd ?

Но это ничего не меняет.
(function webpackUniversalModuleDefinition(root, factory) {
	if(typeof exports === 'object' && typeof module === 'object')
		module.exports = factory();
	else if(typeof define === 'function' && define.amd)
		define(factory);
	else if(typeof exports === 'object')
		exports["mySqr"] = factory();
	else
		root["mySqr"] = factory();
})


Теперь он дополнительно проверяет окружение, не находит ни module.exports, ни define и запихивает в window переменную mySqr, где по прежнему объект с полем default

nerv_ 28.12.2015 00:10

Цитата:

Сообщение от vasa_c
Предлагаете использовать libraryTarget: umd ?

ага. Отсюда вывод:
- или ты что-то делаешь не так
- или компилишь не правильно
- или вебпак глючит
- или тс глючит

У меня нормально работает:
<script src="http://nervgh.github.io/pages/recursive-iterator/dist/recursive-iterator.min.js"></script>
<script>
'use strict';
let root = {
    object: {
        number: 1
    },
    string: 'foo'
};

for(let item of new RecursiveIterator(root)) {
    console.log(item.path.join('.'), item.node);
}
</script>

vasa_c 06.01.2016 16:40

Нет, это всё-таки не umd.

Это бабель слишком умный и если есть только export default, то делает module.export = exports["default"].
Если же есть и дополнительные экспорты, то будет, как обычно объект с полем "default".

Мой typescript не настолько умный, поэтому у меня {default}.
Придётся руками дописывать "lib=lib.default;"


Часовой пояс GMT +3, время: 18:42.