wewowweb / laravel-mix-svelte

mix.svelte();
MIT License
68 stars 10 forks source link

Babel transpile after svelte compilation #7

Closed JoshuaCrewe closed 4 years ago

JoshuaCrewe commented 4 years ago

I am not sure if this is the right place for this issue but I am looking for some help.

I have been trying to add IE11 support to svelte using this extension. Without any use of babel IE11 throws an error const must be initialised as it is using const in a for-of iteration loop. As I understand it, transpiling with babel can transfrom ES6 code to ES5 and remove this issue.

I am repeatedly hitting walls when trying to implement Babel in laravel mix with the added Svelte step. Without Svelte I can do something like :

{
    test: /node_modules\/(specific-module-to-include)\/.+\.js$/,
        use: [
            {
                 loader: 'babel-loader',
                 options: mix.config.babel()
            }
       ]
}

And a .babelrc of :

{
  "presets": ["@babel/preset-env"],
}

When compiling with svelte I get Expected : error in IE which is coming from the Svelte component.

The question is, how to I control the order so that the svelte templtes get comiled and then babel can transpile them to work in IE11 ?

morpheus7CS commented 4 years ago

Hey,

thanks for dropping by. This may not be directly connected to the plugin, but we are at the stage of this repository where we can still field some of these questions in order to provide some helpful feedback.

I don't know if you have a Laracasts subscription (it is worth its weight in gold and has allowed me to start contributing to open source). I did a quick Google search and found this episode: https://laracasts.com/series/learn-laravel-mix/episodes/8

In just case you don't have the subscription, @JeffreyWay lays out these steps:

  1. Find the babel plugin that will give you the desired functionality and install it through npm or yarn
  2. Throw it in a .babelrcfile.
  3. Laravel Mix is smart enough to check for the existence of such a file and merge it with a default file when compiling the JS assets through its .js()function.

Hope that helps.

Kind regards, g

JoshuaCrewe commented 4 years ago

Thanks for the speedy response.

I do have a Laracasts subscription so I will watch that episode and see if it helps. I am pretty sure I have seen it before though.

I don’t know what kind of Babel plugin will give me the functionality I want though. It seemed to me that Babel wasn’t running on the compiled code and trying to work on the original svelte file. Have you ever had success using Babel and svelte?

morpheus7CS commented 4 years ago

Hey Joshua,

I have very little Babel experience. I've done a short look into it. Rich Harris has had two different responses to this question. One was to use polyfills to guarantee IE11 support source and the other I have found was to use Bublé.

Hope this helps your use case. I'll keep this issue open for a while and maybe you can report back on your findings for other users with similar issues.

Kind regards, g

JoshuaCrewe commented 4 years ago

I tell you what. I have been on a journey. It hasn't been fun but I have managed to get IE11 support through the use of babel. There are still some inconsistencies that puzzle me so I am still ironing out the creases.

The issue I was facing wasn't entirely to do with polyfills, that was the second step. The first step was working out that Babel wasn't operating on the compiled Svelte components. I read somewhere that loaders work from right to left in the array. (~I can't remember where but I think somewhere in the Webpack docs about loaders~ webpack docs ). So I ended up with the following webpack config :

webpack.mix.js

mix.webpackConfig({
    resolve: {
        mainFields: ['svelte', 'browser', 'module', 'main'],
        extensions: ['.mjs', '.js', '.svelte'],
        alias: {
            svelte: path.resolve('node_modules', 'svelte'),
        },
    },

    module: {
        rules: [
            {
                test: /\.(svelte)$/,
                use: [
                    {
                        loader: 'babel-loader',
                        options: mix.config.babel(),
                    },
                    {
                        loader: 'svelte-loader',
                    },
                ],
            },
            {
                test: /\.(js|mjs)$/,
                use: [
                    {
                        loader: 'babel-loader',
                        options: mix.config.babel(),
                    },
                ],
            },
        ],
    },
});

.babelrc

{
    "presets": [["@babel/preset-env", {
        "targets": {
            "browsers": [
                "ie >= 11"
            ]
        },
        "useBuiltIns": "entry",
        "corejs": 3
    }]],
    "plugins": []
}

I have added core-js@3 but I don't think it is really doing anything. I used polyfill.io to get all the polyfills needed for what ever code is being written.

@morpheus7CS how do you feel about including config relating to babel in this plugin? The Svelte template doesn't have it but the rollup one does, I am not really sure why that is though. I think Laravel Mix comes bundled with babel support so I don't think we are asking users to add anything new (unlike using buble).

The tricky part for me is knowing what is being used and what is not. So in another project I didn't need to explicitly include options: mix.config.babel(), for .svelte files. I also needed to exclude certainly libraries in another project.

This worked for one ...

{
    test: /\.svelte$/,
    exclude: /node_modules\/(core-js|@babel)/,
    loader: ['babel-loader', 'svelte-loader']
},

while the other needed ...

{
    test: /\.(svelte)$/,
    use: [
        {
            loader: 'babel-loader',
            options: mix.config.babel(),
        },
        {
            loader: 'svelte-loader',
        },
    ],
},

I will say that this has been worked out with deadlines looming and a fix needed quickly so when it works I have not been overly concerned with why or how it can be made better. I plan to figure that out over the coming weeks. The solution does make sense to me though in general i.e. take svelte files, compile them to js, pipe them through babel and add polyfills as needed.

JoshuaCrewe commented 4 years ago

@morpheus7CS any thoughts on this one? I am repeatedly revisiting sveltes integration with Laravel Mix. If you were interested in adding babel support then I could open a PR with the right webpack config to read the relevant babel config.

morpheus7CS commented 4 years ago

Hey @JoshuaCrewe,

I kept the your email in the inbox the entire time and it keeps bugging me that this issue is semi-closed in my mind as well. I would welcome a PR for it, but I would let you take the lead on this one, since this one is a bit far out of my depth here... :sweat_smile:

Thanks for revisiting the issue.

Kind regards,
g

morpheus7CS commented 4 years ago

Hey @JoshuaCrewe,

thanks again for contributing! This is now solved in the v0.1.6 release.

Kind regards,
g