具有webpack和infer-externs的Clojurescript需要具有高级编译功能的未定义对象

时间:2019-07-08 17:34:13

标签: webpack compilation clojurescript clojurescript-javascript-interop

我按照本指南使用了webpack + clojurescript https://clojurescript.org/guides/webpack。当使用:none:whitespace进行编译时,它完美地工作,但是当我使用:advanced进行编译时,挂接到window的对象之一最终被作为未定义对象导入,导致应用崩溃。

我尝试了几件事,例如使用window对象定义和externs.js,但是我发现很难对此进行更深入的研究。

这是我的编译器参数:

{:source-paths ["src/cljs" "src/cljc" "env/prod/cljs"]
             :compiler
             {:output-to     "target/cljsbuild/public/js/app.js"
              :output-dir    "target/cljsbuild/public/js"
              :source-map    "target/cljsbuild/public/js/app.js.map"
              :optimizations :advanced
              :infer-externs true
              :pretty-print  false
              :npm-deps      false
              :foreign-libs [{:file "dist/index_bundle.js"
                              :provides ["react" "react-dom" "react-select" "react-table"]
                              :global-exports {react React
                                               react-dom ReactDOM
                                               react-select Select
                                               react-table ReactTable}}]}}

这是我的index.js,是webpack的入口点

// Here we define what we need.
// Webpack is gonna use this and produce a bundle.
// cljs will read this bundle and provide the namespaces for us.
import React from 'react';
import ReactDOM from 'react-dom';
import Select from 'react-select';
import ReactTable from 'react-table'

window.React = React;
window.ReactDOM = ReactDOM;
window.Select = Select;
window.ReactTable = ReactTable

webpack配置非常简单

module.exports = {
    entry: './src/js/index.js',
    output: {
        filename: 'index_bundle.js'
    }
}

我得到的错误是因为在这样的文件上:

(ns foo
  (:require
   [react-table :as ReactTable]
   [reagent.core :as r]
   [clojure.string :as str]))
[...]
(r/adapt-react-class ReactTable)

ReactTable已绑定到nil。我可以确认在js控制台上window.ReactTable也是nil

只需在编译器选择上将:advanced更改为:whitespace,然后将其他所有内容保持原样即可解决此问题。在js控制台中,window.ReactTable不再是nil

有什么想法吗? :)

-----编辑(添加解决方法信息)--------

我发现此用例的一种可能的解决方法是像这样“拆分” foreign-libs

              :foreign-libs [{:file "dist/main.js"
                              :provides ["react" "react-dom" "react-select"]
                              :global-exports {react React
                                               react-dom ReactDOM
                                               react-select Select}}
                             {:file "dist/react_table.js"
                              :requires ["react" "react-dom"]
                              :provides ["react-table"]
                              :global-exports {react-table ReactTable}}]}}

使webpack配置适应于和入口点会创建两个单独的包,一个包仅包含ReactTable,而另一个包则包含所有其他包。我不认为这是解决方案,因为没有发现真正的问题。但这可以解决问题。

1 个答案:

答案 0 :(得分:0)

您肯定会遇到高级优化问题,这些问题弄乱了您正在使用的库的名称,但是根据您的用例,您可能根本不需要使用Webpack (不确定如果您愿意的话)。

您正在使用的库似乎很受欢迎,可以被CLJSJS project覆盖,因此,如果您找到所需的版本,则可以将库作为常规依赖项添加到{{1}中}文件,它应该可以正常工作。 CLJSJS的软件包包括相关性信息和方便打包的externs文件。

最后,您可能偶然发现了较旧版本的ClojureScript中的错误。检查您使用的是最新版本还是旧版本。