2017-04-05 53 views
3

我在使用012pack在所有设备上正常工作时遇到了一些麻烦,虽然是webpack。如何在webpack/babel构建中使用CustomElement v1 polyfill?

上我的设置一些背景资料: * Webpack2 +巴贝尔-6- *应用程序是用ES6,transpiling到ES5 *导入一个node_module包写入ES6,它定义/登记在应用程序中使用的CustomElement

因此相关的WebPack dev的配置看起来是这样的:

const config = webpackMerge(baseConfig, { 
    entry: [ 
    'webpack/hot/only-dev-server', 
    '@webcomponents/custom-elements/src/native-shim', 
    '@webcomponents/custom-elements', 
    '<module that uses CustomElements>/dist/src/main', 
    './src/client', 
    ], 
    output: { 
    path: path.resolve(__dirname, './../dist/assets/'), 
    filename: 'app.js', 
    }, 
    module: { 
    rules: [ 
     { 
     test: /\.js$/, 
     loader: 'babel-loader', 
     options: { 
      cacheDirectory: true, 
     }, 
     include: [ 
      path.join(NODE_MODULES_DIR, '<module that uses CustomElements>'), 
      path.join(__dirname, '../src'), 
     ], 
     }, 
    ], 
    }, 
... 

钥匙拿走的题: *我需要<module that uses CustomElements> 前CustomElement聚装*我需要<module that uses CustomElements>在我的应用程序之前加载 * <module that uses CustomElements>是ES6,因此我们正在对它进行编译(因此包含在babel-loader中)。

如预期在现代ES6浏览器(IE的桌面版Chrome)以上的作品,无论其

它不会在旧的浏览器。我碰到下面的错误在旧的浏览器,例如iOS的8:

SyntaxError: Unexpected token ')' 

指向开放匿名函数在本机垫片pollyfill:

(() => { 
    'use strict'; 

    // Do nothing if `customElements` does not exist. 
    if (!window.customElements) return; 

    const NativeHTMLElement = window.HTMLElement; 
    const nativeDefine = window.customElements.define; 
    const nativeGet = window.customElements.get; 

所以在我看来,像native-shim会必须transpiled到ES5:

 include: [ 
+   path.join(NODE_MODULES_DIR, '@webcomponents/custom-elements/src/native-shim'), 
      path.join(NODE_MODULES_DIR, '<module that uses CustomElements>'), 
      path.join(__dirname, '../src'), 
     ], 

...但这样做,现在都打破的Chrome和iOS 8,出现以下错误:

app.js:1 Uncaught TypeError: Failed to construct 'HTMLElement': Please use the 'new' operator, this DOM object constructor cannot be called as a function. 
    at new StandInElement (native-shim.js:122) 
    at HTMLDocument.createElement (<anonymous>:1:1545) 
    at ReactDOMComponent.mountComponent (ReactDOMComponent.js:504) 
    at Object.mountComponent (ReactReconciler.js:46) 
    at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371) 
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258) 
    at Object.mountComponent (ReactReconciler.js:46) 
    at Object.updateChildren (ReactChildReconciler.js:121) 
    at ReactDOMComponent._reconcilerUpdateChildren (ReactMultiChild.js:208) 
    at ReactDOMComponent._updateChildren (ReactMultiChild.js:312) 

..这把我带到这个constructor()线在本机垫片:

window.customElements.define = (tagname, elementClass) => { 
    const elementProto = elementClass.prototype; 
    const StandInElement = class extends NativeHTMLElement { 
     constructor() { 

唷。所以我很不清楚我们如何在基于webpack的构建中实际包含它,其中使用CustomElements的依赖项是ES6(并且需要转译)。

  • Transpiling本地-垫片来ES5采用原生垫片作为-是在束进入点的顶部为iOS 8不工作不工作
  • ,但确实为Chrome
  • 不包括Chrome浏览器和iOS的原生游戏破解版

在这一点上,我对Web组件非常沮丧。我只想使用这种依赖性,它恰好与Web组件一起构建。我如何才能让它在webpack构建中正常工作,并在所有设备上工作?我在这里错过了很明显的东西吗

我的。babelrc配置为后人着想(DEV配置最相关的):

{ 
    "presets": [ 
    ["es2015", { "modules": false }], 
    "react" 
    ], 
    "plugins": [ 
    "transform-custom-element-classes", 
    "transform-object-rest-spread", 
    "transform-object-assign", 
    "transform-exponentiation-operator" 
    ], 
    "env": { 
    "test": { 
     "plugins": [ 
     [ "babel-plugin-webpack-alias", { "config": "./cfg/test.js" } ] 
     ] 
    }, 
    "dev": { 
     "plugins": [ 
     "react-hot-loader/babel", 
     [ "babel-plugin-webpack-alias", { "config": "./cfg/dev.js" } ] 
     ] 
    }, 
    "dist": { 
     "plugins": [ 
     [ "babel-plugin-webpack-alias", { "config": "./cfg/dist.js" } ], 
     "transform-react-constant-elements", 
     "transform-react-remove-prop-types", 
     "minify-dead-code-elimination", 
     "minify-constant-folding" 
     ] 
    }, 
    "production": { 
     "plugins": [ 
     [ "babel-plugin-webpack-alias", { "config": "./cfg/server.js" } ], 
     "transform-react-constant-elements", 
     "transform-react-remove-prop-types", 
     "minify-dead-code-elimination", 
     "minify-constant-folding" 
     ] 
    } 
    } 
} 
+0

也许这款车的帮助:http://stackoverflow.com/a/43007474/4600982 – Supersharp

+0

@Supersharp感谢您的评论。看看es5-adapter,它看起来与自定义元素回购(https://github.com/webcomponents/custom-elements/blob/master/src/native-shim.js)中的native-shim完全相同我在OP中提到。这解决了ES6兼容浏览器的问题,但不适用于较老的iOS。 :( – Prefix

+0

我不知道它们是否相同,但不应该转换适配器。 – Supersharp

回答

0

我是能够实现与下面的.babelrc插件管道类似的东西。它看起来像,唯一的区别是https://babeljs.io/docs/plugins/transform-es2015-classes/https://babeljs.io/docs/plugins/transform-es2015-classes/,但老实说,我不记得是专门解决什么问题的:

{ 
    "plugins": [ 
    "transform-runtime", 
    ["babel-plugin-transform-builtin-extend", { 
     "globals": ["Error", "Array"] 
    }], 
    "syntax-async-functions", 
    "transform-async-to-generator", 
    "transform-custom-element-classes", 
    "transform-es2015-classes" 
    ] 
}