Hello! How can I setup my build to NOT generate so...
# javascript
r
Hello! How can I setup my build to NOT generate sourceMaps? We don't need it, its large file and probably it slows build a little. I tried:
Copy code
browser {
    webpackTask {
        sourceMaps = false
    }
}
Copy code
browser {
    commonWebpackConfig {
        sourceMaps = false
    }
}
Copy code
browser {
    commonWebpackConfig {
        devtool = "none"
    }
}
But nothing works. After calling task xxxBrowserDistribution, source maps are always generated It was tested on Kotlin 1.7 and IR backend
t
AFAIK Source Map disabling doesn’t work in 1.7 Related issue exists
r
I tried to add code from example:
Copy code
afterEvaluate {
    tasks.configureEach {
        when (this) {
            is KotlinJsCompile -> {
                kotlinOptions {
                    sourceMap = false
                    sourceMapEmbedSources = null
                }
            }

            is KotlinWebpack -> {
                sourceMaps = false
            }
        }
    }
}
(configureEach was not generic type, so I had to make comparsion in when statement) But still no luck, source map is generated. Are you saying that in 1.7 there is no way to disable source maps?
Kotlin
1.8+
required :(
v
Also, don't use
afterEvaluate
(when totally unnecessary like here when using
configureEach
, but generally always). And better do
Copy code
tasks.withType<KotlinJsCompile>().configureEach { ... }
tasks.withType<KotlinWebpack>().configureEach { ... }
👍 1
t
afterEvaluate
in my plugin unfortunately required in IR, otherwise default settings will be applied 😞
v
There are cases where for example some plugins use
afterEvaluate
and you have to use
afterEvaluate
to mitigate that. Or where you need to wire legacy non-lazy properties and do not have much chance without using
afterEvaluate
. But the given case, using
configureEach
within
afterEvaluate
is just unnecessary noise, as
configureEach
also works on elements added in the future already. 🙂
a
@Vampire do you have a link to an article/slack discussion in regards to these subtle gradle things. I'd like to be informed more about • configureEach vs afterEvaluate • task.create vs task.register
v
Not something in particular. But simply never use
afterEvaluate
except as very very very very last resort, because usually it is just symptom treatment for the price of adding timing and ordering problems and race conditions, which then lead to even harder to debug problems later on. It is like calling
SwingUtilities.invokeLater
to "fix" UI problems. Or
Thread.sleep
to "fix" multi-threading problems. Regarding
configureEach
vs.
afterEvaluate
, this is not really a "versus".
configureEach
simply configures every object in that collection as soon as it gets realized, and also objects added to that collection later on. The more appropriate "versus" would be
all
, which does the same as
configureEach
but causes each element in the collection to be immediately realized and configured and thus breaks laziness and task configuration avoidance.
afterEvaluate
simply adds an action to a queue that should be done "after evaluation / configuration was done". But this of course mainly brings timing and ordering problems and race conditions. For example one plugin wants to set a property of an extension depending on some user-configured value. So the bad way is to use
afterEvaluate
and there evaluate the user-set value to set the property. If now some user code or other plugin wants to do something with that property, it has to be aware that this plugin changes the value in
afterEvaluate
, and itself so the intended logic in an
afterEvaluate
, that must be scheduled only after the plugin scheduled it's action to get the right value. Just one example of the horrible cascading mess it brings. To mitigate that, the lazy property / provider APIs were introduced, so that instead of getting the value and doing some calculation with it immediately you can write properties together and calculate one from the other as late as possible, optimally only at execution time when all configuration was done already.
task.create
vs.
task.register
is again shut the same as
configureEach
vs.
all
.
create
creates and realizes a task immediately and unconditionally.
register
is part of task configuration avoidance and just registers that a task of given name is available and how to configure it if it is needed. So unless you have something that breaks task configuration avoidance, only those tasks that are actually going to be executed will be realized and configured. So the simple rule is to always use
register
unless you have one of the very rare cases where you cannot, and avoid the documented methods that break it like
tasks.withType() { ... }
,
tasks. all
, unguarded
tasks.matching
,
tasks.getByName
, and so on and so forth
a
This puts more into light. Thanks So, what should use instead of
tasks.withType(){}
?
v
tasks.withType(){}
is just syntactic sugar for
tasks.withType().all {}
(because both were there before task-configuration avoidance existed / lazy registering existed). Now guess. 🙂 Besides that most of the appropriate replacements are documented at https://docs.gradle.org/current/userguide/task_configuration_avoidance.html
One thing that is not documented there for example is, if you have something
tasks.matching { it.name == "foo" }.configureEach { ... }
the page mentions it is bad and should be guarded with a
withType
to narrow down the bad effect as far as possible. But that advice is only good if you need that task collection as collection for something. If you just want to configure the matched tasks,
tasks.configureEach { if (it.name == "foo") { ... } }
would be the proper replacement.
a
Thanks a lot for the in depth to these concepts. They are harder to grasp for one who started to deep dive into gradle while they (gradle team) were embracing task configuration avoidance
v
You're welcome. If you can use build
--scans
it is easiest properly adopt task configuration avoidance as it tells you which tasks were realized at configuration time and this value should be near to zero