I followed this guide on using webpack + clojurescript, https://clojurescript.org/guides/webpack. It works perfectly when compiled with :none
or :whitespace
, but when I compile with :advanced
one of the objects hooked to the window
ends up being imported as an undefined object, causing the app to crash.
I tried a couple of things, like defining and externs.js
with the window object, but I find it hard to dig deeper on this.
This is my compiler arguments:
{: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}}]}}
This is my index.js, entrypoint for 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
The webpack config is as simple as
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'index_bundle.js'
}
}
The error I get is because on a file like this:
(ns foo
(:require
[react-table :as ReactTable]
[reagent.core :as r]
[clojure.string :as str]))
[...]
(r/adapt-react-class ReactTable)
ReactTable is bound to nil
. I can confirm that on the js console window.ReactTable
is also nil
.
Simply changing :advanced
to :whitespace
on the compiler opts, and leaving everything else as-is, solves the issue. And in the js console, window.ReactTable
is no longer nil
.
Any ideas? :)
----- EDIT (adding workaround info) --------
I found that a possible work-around for this use case is to "split" the foreign-libs
like this:
: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}}]}}
adapting the webpack config to and entrypoints create two separate bundles, one with only ReactTable
and the other with all others. I don't consider this to be a solution because the real problem was not identified. But doing so solves the issue.