Tailwindcss: Lodash tree-shaking

Created on 6 Jan 2018  Â·  14Comments  Â·  Source: tailwindlabs/tailwindcss

I’ve pin-pointed in a project that lodash is not tree-shaken within the tailwind code base. As such, I’m not able to shake it myself as tailwind pulls the _ object in, making my attempts redundant.

Given that tailwind doesn’t use much of lodash, I think it would be a good decision to ‘shake things up’ 😉.


Aside…

I’m new to all of this (world of webpack and modules), but a colleague has also told me about the modularised version of lodash. Can’t see how it’s better than shaking, but perhaps also worth consideration…

Most helpful comment

Yeah Tailwind should be installed as a dev dependency for building stuff locally only; it should never be reaching your actual application bundle that you send to the client so this sounds like a configuration issue maybe? What we do with Tailwind's dependencies internally shouldn't have any impact on the JS you serve to the client.

All 14 comments

What do you need to treeshake tailwind for? You're not bundling tailwind JS into your app...

Yeah Tailwind should be installed as a dev dependency for building stuff locally only; it should never be reaching your actual application bundle that you send to the client so this sounds like a configuration issue maybe? What we do with Tailwind's dependencies internally shouldn't have any impact on the JS you serve to the client.

I’m trying to tree-shake lodash, not tailwind. Unless I’m misunderstanding something here?

Tailwind shouldn't be in your bundle though, so you should be able to tree shake lodash out of your bundle without Tailwind having any impact on it. Webpack should not be looking at Tailwind and seeing "oh this package uses all of lodash so we can't treeshake it" because Webpack shouldn't be looking at Tailwind at all.

I'm not a Webpack expert but I have to believe there's an issue with configuration here somewhere; Webpack should only be considering the code that's actually shipped to the client when tree shaking; it shouldn't be taking into account what a local dependency that's not bundled (like Tailwind) is depending on.

I see, so it’s not actually Tailwind, it’s what’s described in this article:

Without using babel and babel-plugin-lodash there is currently no way how to tree shake lodash, if you wanna use concise import without subpaths => import { get } from ‘lodash-es’.

So my conclusion was pretty much an assumption then… Sorry about that.

cc https://github.com/webpack/webpack/issues/1750

@adamwathan I think my issue here is related to this thread.

I noticed when I want to import some variables from tailwind into my app:
import {screens} from '../../../../tailwind.config'

I get lodash imported into my webpack bundle, which probs means it's importing some other tailwind assets.

Is there a different way I should referencing these vars, or maybe a different webpack config?

I think this maybe be causing the issue here https://github.com/tailwindcss/discuss/issues/50#issuecomment-441997940 as well

@knynkwl Is it still an issue if you use resolveConfig? Released in v1.0.0-beta.6 #877
It uses a few lodash functions but they are directly imported.

@tlgreg I'm still getting lodash in my bundle.

I updated to ^1.0.0-beta.8

I removed all code in my app.js except:

import resolveConfig from 'tailwindcss/resolveConfig'
import tailwindConfig from '../../tailwind.config.js'

const config = resolveConfig(tailwindConfig)

This is what my bundle report shows:
Screenshot 2019-05-11 at 10 51 46 PM

Are we sure that's pulling in _all_ of lodash? resolveConfig only pulls in a few lodash methods:

https://github.com/tailwindcss/tailwindcss/blob/next/src/util/resolveConfig.js#L1-L5

@adamwathan I from what I am seeing it's pulling in more than just those 5.

Here is my app and bundle: https://gist.github.com/knynkwl/c3100b64236e27290dd6b47327e2235e

But ideally we shouldn't have any lodash in the bundle, only the config file, right?

Doing import tailwind from '../../tailwind.config.js' seems to not let lodash in, but I get:

WARNING in ./src/js/app.js 3:12-20
    "export 'default' (imported as 'tailwind') was not found in '../../tailwind.config.js'

since it's module.exports = {}

But ideally we shouldn't have any lodash in the bundle, only the config file, right?

In a perfect world yes but lodash is required to resolve the contents of your config file — we use a bunch of its functions to do the actual merging logic.

You could generate a flattened/static version of your config as part of your build process and import that so you don't need the resolveConfig function, that way you wouldn't need lodash to create the final config on demand.

Checked your bundle, it's not pulling in all of lodash, only the parts we use. You can see it doesn't contain functions like partition, intersection, zipObject, etc. etc. I'll see about re-implementing the parts of lodash we use in a minimal way to avoid the dependency altogether but for now parts of lodash are necessary to actually resolve the final config object.

This actually seemed to solve the problem. No Lodash anymore ;)

import { theme } from '../../../tailwind.config';
const {screens } = theme;
Was this page helpful?
0 / 5 - 0 ratings

Related issues

jvanbaarsen picture jvanbaarsen  Â·  3Comments

lamberttraccard picture lamberttraccard  Â·  3Comments

dbpolito picture dbpolito  Â·  3Comments

smbdelse picture smbdelse  Â·  3Comments

jbardnz picture jbardnz  Â·  3Comments