Search code examples
vue.jswebpackbabel-loaderbabel-polyfill

Why isn't my Babel-Loader converting my vendor code to be valid for IE8+?


I'm using the latest Webpack, Babel and Babel-Loader in my Vue.js app.

I'm trying to have my code run on IE 8, 9 and 10 but it doesn't.

The problem is that IE10 and under complain that const is invalid syntax. I can see that this is coming from my vendors~index.bundle.js file. This file contains code that isn't mine.

In particular, I can see that the const is from a Vue addon that I'm using called vue-snotify.

Why isn't babel converting my vendor code to be valid for IE10 and under?

.babelrc

{
    "presets": [
        [
            "@babel/preset-env", {
                "useBuiltIns": "entry",
                "shippedProposals": true
            }
        ]
    ]
}

.browserslistrc

ie >= 8

.webpack.config.js

const path = require('path')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = {
    mode: 'production',
    devtool: false,
    performance: {
        hints: false
    },
    entry: {
        index: './src/ui/index.js',
        style:'./src/ui/app.sass'
    },
    output: {
        path: path.resolve(__dirname, 'build/public/static'),
        filename: 'js/[name].bundle.js',
        chunkFilename: 'js/[name].bundle.js',
        publicPath: 'static/'
    },
    optimization: {
        splitChunks: {
            chunks: 'all'
        }
    },
    module: {
        rules: [
            {
                test: /\.m?js$/,
                exclude: /node_modules/,
                loader: 'babel-loader'
            },
            {
                test: /\.vue$/,
                exclude: '/node_modules/',
                loader: 'vue-loader'
            },
            {
                test: /\.pug$/,
                loader: 'pug-plain-loader'
            },
            {
                test: /\.sass$/,
                use: [
                    'vue-style-loader',
                    'css-loader',
                    {
                        loader: 'sass-loader',
                        options: {
                            indentedSyntax: true
                        }
                    }
                ]
            },
            {
                test: /\.(png|jpg|jpeg|gif)$/,
                loader: 'file-loader',
                options: {
                    name: '[hash].[ext]',
                    outputPath: 'assets/'
                }
            },
            {
                test: /\.(woff2?|eot|ttf|otf|svg)(\?.*)?$/,
                use: 'url-loader?limit=10000'
            }
        ]
    },
    plugins: [
        new VueLoaderPlugin(),
        new CopyWebpackPlugin([
            { from: 'src/server/app', to: '../../app' },
            { from: 'src/server/public', to: '../' },
            { from: 'src/server/vendor', to: '../../vendor' }
        ])
    ],
    resolve: {
        alias: {
            '@components': path.resolve(__dirname, 'src/ui/components'),
            '@store': path.resolve(__dirname, 'src/ui/Store'),
            '@assets': path.resolve(__dirname, 'src/ui/assets')
        },
        extensions: ['.js', '.vue']
    }
}

Solution

  • Generally, package maintainers are encouraged to package sources that do not require additional transpilation steps or tooling to use. Babel enforces this by not transpiling modules that are under a node_modules/ subpath (also to avoid introducing support or accidentally transpiling Babel-related sources).

    This is not a working solution, but it should set you off in the right direction:

    {
        test: /\.m?js$/,
        include: [
          path.resolve(__dirname, 'src'),    // Include your sources.
          require.resolve('vue-snotify')     // Include `vue-snotify` main module.
        ],
        loader: 'babel-loader',
        options: {
            // Babel has it's own defaults, so these have to be edited as well.
            include: [
                require.resolve('vue-snotify')
            ]
        }
    }
    

    You can always debug Babel and get information on what sources it skipped transpiling because they matched ignore patterns by configuring debug when running:

    DEBUG=babel* webpack
    

    Given your setup right now, Babel should never receive a request for vue-snotify if you debugged. So first step would be to actually see that Babel is receiving a request to transpile vue-snotify and then further configure babel-loader to not ignore it's path.