Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

babel-loader

Keep on Learning!

If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.

Start your All-Access Pass
Buy just this tutorial for $12.00

With a Subscription, click any sentence in the script to jump to that part of the video!

Login Subscribe

RepLogApp uses the ES6 class syntax. And, at the end of the last tutorial, we used a tool called Babel to transpile this new ES6 code to older code that will run on older browsers. But... we lost that when we moved to Webpack. Yep, if you look at the dumped rep_log.js file and search for class RepLogApp, there it is! Still using the ES6 class syntax.

Installing babel-loader

It's time to bring Babel back. How? Well, we still have the .babelrc file from the last tutorial, which configures Babel to do the transpiling we want:

4 lines .babelrc
{
"presets": ["env"]
}

So if we could somehow tell Webpack to pass all .js files through Babel... we'd be done!

How do we do this? How can we tell Webpack to filter our code through something external? With a very powerful system in Webpack called loaders. Google for "babel-loader" and find its GitHub page. Let's get this guy installed. Copy the yarn add line, though we already have webpack installed.

Find your terminal and run it with --dev on the end:

yarn add babel-loader@7 babel-core babel-preset-env --dev

Tip

Latest version of babel-loader requires a newer version of Babel - so we’re staying on version 7.

This installs Babel itself and the env preset: both things we installed in the last tutorial. It also installed babel-loader.

About Loaders

Here's how the loader system works. In Webpack, you can say:

Yo, Webpack! When I require this file, I want you to send it through this loader so that it can make whatever changes it wants.

In this case, we want to send RepLogApp through babel-loader. How? Of course, there are two ways.

The Inline Loader Sytnax

The first is a special syntax right when you require the module. Before the name of the module, add babel-loader!:

... line 1
const RepLogApp = require('babel-loader!./Components/RepLogApp');
... lines 3 - 8

Read this from right to left. It says: require this module and then pass it through babel-loader. You can even have multiple loaders, each separated by an exclamation mark, processing from right to left. Each loader can even accept options via query parameters when using this syntax.

Let's try it! Refresh! Yes.... nothing is broken. And in the built rep_log.js file, search for RepLogApp. The class key is gone! Replaced by fancy code that mimics its behavior.

Babel is back!

Using a Loader Globally

This is great! Except that I do not want to have to add this to every require statement! Thankfully, Webpack also has a global way to apply loaders.

Remove the inline loader syntax:

... line 1
const RepLogApp = require('./Components/RepLogApp');
... lines 3 - 8

And open webpack.config.js. Add a new module key set to {} and a sub-key called rules set to an array:

... lines 1 - 3
module.exports = {
... lines 5 - 13
module: {
rules: [
... lines 16 - 21
]
},
... lines 24 - 29
};

Here's the deal: each rule will contain a filename regular expression and a loader that should be applied whenever a file matches that. Add {} for this first loader with a test key. We want to apply the loader to all files that end in .js:

... lines 1 - 3
module.exports = {
... lines 5 - 13
module: {
rules: [
{
test: /\.js$/,
... lines 18 - 20
}
]
},
... lines 24 - 29
};

That's what this regular expression matches. Below this, add use, with loader: 'babel-loader':

... lines 1 - 3
module.exports = {
... lines 5 - 13
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader'
}
}
]
},
... lines 24 - 29
};

That is it! Now, every .js file will go through Babel! Woohoo!

Restart the webpack script:

./node_modules/.bin/webpack --watch

And check out the built rep_log.js file. Try to find RepLogApp again. Yep, the same, beautiful, transpiled code.

Leave a comment!

20
Login or Register to join the conversation
KevinC Avatar
KevinC Avatar KevinC | posted 4 years ago | edited

there I'm getting confused between your symfonycast about babel-loader and what I find here: https://symfony.com/doc/current/frontend/encore/babel.html

What's the real solution? I'm on symfony 4.2, webpack 4
I'm simply trying to get everything to run through Babel so I can support Internet Explorer 11. The link to the article above makes me think I can just call:
`
.configureBabel(function(babelConfig) {

})

`
in my webpack.config.js and be done, but it doesn't seem to be helping my IE 11 issues. Specifically when I load a page in IE 11 it claims it can't load jQuery because of syntax errors in
SCRIPT1002: Syntax error
app.85970cb9.js (47,110177)

Which is the main webpack entry point. How can I really know if it's "transpiling" for IE 11?
Thanks,
Kevin

Reply
KevinC Avatar
KevinC Avatar KevinC | KevinC | posted 4 years ago | edited

Also resolved this non-sense too, I had to end up including all the node_modules via "includeNodeModules" in .configureBabel(). Now my code works in IE 11.

`
Encore
...
.configureBabel(function(babelConfig) {

},{
    includeNodeModules: [
        'jquery','bootstrap','jquery-ui','jquery-ui/ui/widgets/tooltip',
        'slick-carousel','jquery-match-height','jquery-validation','jquery.maskedinput/src/jquery.maskedinput',
        'jquery-placeholder','jquery-scrollTo'
    ]
})

;
`

Reply

Hey Kevin

Yeah this is the solution! Not perfect but if you want to support something outdated it's so.

Cheers!

Reply
KevinC Avatar
KevinC Avatar KevinC | posted 4 years ago | edited

there , howdy friend. I'm getting this when I try compile dev via : yarn run encore dev --watch

I used the following to add modules;
yarn add babel-loader@7 babel-core babel-preset-env --dev

Thoughts?

error in ./assets/js/main.js

Module build failed (from ./node_modules/babel-loader/lib/index.js):
Error: Requires Babel "^7.0.0-0", but was loaded with "6.26.3". If you are sure you have a compatible version of @babel/core, it is likely that something in your build process is loading the wrong version. Inspect the stack trace of this error to look for the first entry that doesn't mention "@babel/core" or "babel-core" to see what is calling Babel.
at throwVersionError (/private/var/www/website/node_modules/@babel/helper-plugin-utils/lib/index.js:65:11)
at Object.assertVersion (/private/var/www/website/node_modules/@babel/helper-plugin-utils/lib/index.js:13:11)
at api (/private/var/www/website/node_modules/@babel/plugin-syntax-dynamic-import/lib/index.js:19:7)
at /private/var/www/website/node_modules/@babel/helper-plugin-utils/lib/index.js:19:12
at Function.memoisePluginContainer (/private/var/www/website/node_modules/babel-core/lib/transformation/file/options/option-manager.js:113:13)
at Function.normalisePlugin (/private/var/www/website/node_modules/babel-core/lib/transformation/file/options/option-manager.js:146:32)
at /private/var/www/website/node_modules/babel-core/lib/transformation/file/options/option-manager.js:184:30
at Array.map (<anonymous>)
at Function.normalisePlugins (/private/var/www/website/node_modules/babel-core/lib/transformation/file/options/option-manager.js:158:20)
at OptionManager.mergeOptions (/private/var/www/website/node_modules/babel-core/lib/transformation/file/options/option-manager.js:234:36)
at OptionManager.init (/private/var/www/website/node_modules/babel-core/lib/transformation/file/options/option-manager.js:368:12)
at File.initOptions (/private/var/www/website/node_modules/babel-core/lib/transformation/file/index.js:212:65)
at new File (/private/var/www/website/node_modules/babel-core/lib/transformation/file/index.js:135:24)
at Pipeline.transform (/private/var/www/website/node_modules/babel-core/lib/transformation/pipeline.js:46:16)
at transpile (/private/var/www/website/node_modules/babel-loader/lib/index.js:50:20)
at /private/var/www/website/node_modules/babel-loader/lib/fs-cache.js:118:18
at ReadFileContext.callback (/private/var/www/website/node_modules/babel-loader/lib/fs-cache.js:31:21)
at FSReqWrap.readFileAfterOpen [as oncomplete] (fs.js:237:13)

Reply

Hey Kevin

Have you seen this thread on Github? in there might be your solution: https://github.com/babel/ba...

If not let us know. Cheers!

Reply
KevinC Avatar
KevinC Avatar KevinC | KevinC | posted 4 years ago | edited

Actually Kevin post below helped me out.

Reply
KevinC Avatar

Actually, I was wrong, it doesn't fix it, I still get the same issue.

Reply

What's your package.json look like? I'm guessing something is mixing versions...

Also, try yarn why babel-loader and yarn why babel. Also, try completely removing node_modules and re-running yarn install just in case.

Cheers!

Reply
KevinC Avatar
KevinC Avatar KevinC | weaverryan | posted 4 years ago | edited

Yeah I ended up cleaning/deleting things and finally got it to compile using:
yarn add babel-loader babel-core, now package.json is:
`"dependencies": {

"babel-core": "^6.26.3",
"babel-loader": "^8.0.6",
...

}`

Of course I also updated my @symfony/webpack-encore so now I'm at: @symfony/webpack-encore@0.27.0 which seems to be webpack 4 and that has broken my build for scss stuff because it's having issues with image paths that were working fine in webpack 2.

So now I'm struggling to compile completely - I may have to downgrade back to webpack 3 and possibly 2.
Frustrating stuff for sure.

Thanks for all the replies.

Reply

Hey Kevin!

Good working debugging! Yes, this is the curse of the Node world at this point - so many packages, so many versions, and things moving so fast. Encore "insulates" you from much of that, but not completely. About the image paths in Webpack 4, those breaking is very possible - you may just need to modify them. For example, an internal library that is used in scss for paths was also upgraded, and it actually fixed some "bugs" in how the paths worked. We recently had some image paths break after an upgrade here on SymfonyCasts... and I realized that the way I wrote the old paths didn't make as much sense as the way that I was supposed to right them now (originally, paths were relative to the "main" scss file, but not the actual scss file I was writing the path in - after the upgrade, all paths were relative to the actual scss file where I was writing the path).

Anyways, if you have some specific errors, feel free to drop them here.

Cheers!

Reply
MichalWilczynski Avatar
MichalWilczynski Avatar MichalWilczynski | posted 4 years ago

Instead of use command from the script, simply run this command:
yarn add babel-loader@7 babel-core@6.26.3 babel-preset-env@1.7.0 --dev
and everything should work ;3

Reply

Hey Michal,

Thanks for sharing your solution with others!

Cheers!

Reply
Lijana Z. Avatar
Lijana Z. Avatar Lijana Z. | posted 4 years ago

wow from - from right to left. They could have made it something more complicated than that, so that no noobs would understand.

Reply

Hey Lijana Z.!

I don't love this syntax either. Fortunately, in practice, you rarely see it. We show it here to learn how things work, step-by-step. But, in the "wild", we use the "rules" to specify the loaders by file type. I almost never need to use this syntax.

Cheers!

Reply
Galen S. Avatar
Galen S. Avatar Galen S. | posted 4 years ago

I see in the included pdf the tip:
"This tutorial uses Webpack v3, so please double check that you do too, otherwise, you will run into some
troubles in further chapters"

Unfortunately I installed the wrong version of webpack going through the tutorial and made a big mess of it. If you're like me and see:

ERROR in ./web/assets/js/Components/RepLogApp.js (./node_modules/babel-loader/lib!./web/assets/js/Components/RepLogApp.js)
Module build failed (from ./node_modules/babel-loader/lib/index.js):
Error: Cannot find module '@babel/core'
babel-loader@8 requires Babel 7.x (the package '@babel/core'). If you'd like to use Babel 6.x ('babel-core'), you should install 'babel-loader@7'.

Than that is probably your issue.

From the page: https://webpack.js.org/load...
Install
webpack 4.x | babel-loader 8.x | babel 7.x
npm install -D babel-loader @babel/core @babel/preset-env webpack

webpack 4.x | babel-loader 7.x | babel 6.x
npm install -D babel-loader@7 babel-core babel-preset-env webpack

Webpack 3 is not mentioned there. So I installed webpack 4 and was able to use the second command but with yarn and everything appears to be working so far.

Reply
Walid-M Avatar

I added babel-loader 7 in webpack 3. It work fine

There is my devDependencies

"babel-core": "^6.26.3",
"babel-loader": "7",
"babel-preset-env": "^1.7.0",
"bootstrap3": "^3.3.5",
"jquery": "^3.3.1",
"sweetalert2": "^7.29.1",
"webpack": "3"

1 Reply
KevinC Avatar
KevinC Avatar KevinC | Walid-M | posted 4 years ago | edited

I thought webpack comes through @symfony/webpack-encore, why are you installing it from yarn as well, doesn't that give unexpected results? I recall seeing an orange message stating such things. And the 'yarn add babel-loader@7 babel-core babel-preset-env webpack' didn't work anyway, it still dies with build error:

Which resulted in the following package.json related contents:

`"dependencies": {

"babel-core": "^6.26.3",
"babel-loader": "7",
"babel-preset-env": "^1.7.0",
"webpack": "^4.32.0"

},`
Module build failed (from ./node_modules/babel-loader/lib/index.js):
Error: Requires Babel "^7.0.0-0", but was loaded with "6.26.3". If you are sure you have a compatible version of @babel/core, it is likely that something in your build process is loading the wrong version. Inspect the stack trace of this error to look for the first entry that doesn't mention "@babel/core" or "babel-core" to see what is calling Babel.

at throwVersionError (/private/var/www/www.vspdirect.com/node_modules/@babel/helper-plugin-utils/lib/index.js:65:11)
at Object.assertVersion (/private/var/www/www.vspdirect.com/node_modules/@babel/helper-plugin-utils/lib/index.js:13:11)
at api (/private/var/www/www.vspdirect.com/node_modules/@babel/plugin-syntax-dynamic-import/lib/index.js:19:7)
at /private/var/www/www.vspdirect.com/node_modules/@babel/helper-plugin-utils/lib/index.js:19:12
at Function.memoisePluginContainer (/private/var/www/www.vspdirect.com/node_modules/babel-core/lib/transformation/file/options/option-manager.js:113:13)
at Function.normalisePlugin (/private/var/www/www.vspdirect.com/node_modules/babel-core/lib/transformation/file/options/option-manager.js:146:32)
at /private/var/www/www.vspdirect.com/node_modules/babel-core/lib/transformation/file/options/option-manager.js:184:30
at Array.map (<anonymous>)
at Function.normalisePlugins (/private/var/www/www.vspdirect.com/node_modules/babel-core/lib/transformation/file/options/option-manager.js:158:20)
at OptionManager.mergeOptions (/private/var/www/www.vspdirect.com/node_modules/babel-core/lib/transformation/file/options/option-manager.js:234:36)
at OptionManager.init (/private/var/www/www.vspdirect.com/node_modules/babel-core/lib/transformation/file/options/option-manager.js:368:12)
at File.initOptions (/private/var/www/www.vspdirect.com/node_modules/babel-core/lib/transformation/file/index.js:212:65)
at new File (/private/var/www/www.vspdirect.com/node_modules/babel-core/lib/transformation/file/index.js:135:24)
at Pipeline.transform (/private/var/www/www.vspdirect.com/node_modules/babel-core/lib/transformation/pipeline.js:46:16)
at transpile (/private/var/www/www.vspdirect.com/node_modules/babel-loader/lib/index.js:50:20)
at /private/var/www/www.vspdirect.com/node_modules/babel-loader/lib/fs-cache.js:118:18
at ReadFileContext.callback (/private/var/www/www.vspdirect.com/node_modules/babel-loader/lib/fs-cache.js:31:21)
at FSReqWrap.readFileAfterOpen [as oncomplete] (fs.js:237:13)`
Reply

I replied your other message. Let's see if it fixes the problem :)

Reply

Hey Walid,

Thanks for sharing it with other users!

Cheers!

Reply

Hi Galen S.!

Ah! I'm really sorry about this! When we add notes to the script or PDF, we then also add them to the video - but that process is sometimes delayed. That's what happened in this case - the note has not yet been added to the video. My apologies - that's really annoying!

Anyways, thanks for posting your notes! The Webpack world moves quickly!

Cheers!

Reply
Cat in space

"Houston: no signs of life"
Start the conversation!

This tutorial explains the concepts of an old version of Webpack using an old version of Symfony. The most important concepts are still the same, but you should expect significant differences in new versions.

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": "^7.2.0",
        "symfony/symfony": "3.3.*", // v3.3.16
        "twig/twig": "2.10.*", // v2.10.0
        "doctrine/orm": "^2.5", // v2.7.0
        "doctrine/doctrine-bundle": "^1.6", // 1.10.3
        "doctrine/doctrine-cache-bundle": "^1.2", // 1.3.5
        "symfony/swiftmailer-bundle": "^2.3", // v2.6.3
        "symfony/monolog-bundle": "^2.8", // v2.12.1
        "symfony/polyfill-apcu": "^1.0", // v1.4.0
        "sensio/distribution-bundle": "^5.0", // v5.0.22
        "sensio/framework-extra-bundle": "^3.0.2", // v3.0.26
        "incenteev/composer-parameter-handler": "^2.0", // v2.1.2
        "friendsofsymfony/user-bundle": "^2.0", // v2.1.2
        "doctrine/doctrine-fixtures-bundle": "~2.3", // v2.4.1
        "doctrine/doctrine-migrations-bundle": "^1.2", // v1.3.2
        "composer/package-versions-deprecated": "^1.11", // 1.11.99
        "friendsofsymfony/jsrouting-bundle": "^1.6" // 1.6.0
    },
    "require-dev": {
        "sensio/generator-bundle": "^3.0", // v3.1.6
        "symfony/phpunit-bridge": "^3.0" // v3.3.5
    }
}

What JavaScript libraries does this tutorial use?

// package.json
{
    "dependencies": [],
    "devDependencies": {
        "babel-core": "^6.25.0", // 6.25.0
        "babel-loader": "^7.1.1", // 7.1.1
        "babel-plugin-syntax-dynamic-import": "^6.18.0", // 6.18.0
        "babel-preset-env": "^1.6.0", // 1.6.0
        "bootstrap-sass": "^3.3.7", // 3.3.7
        "clean-webpack-plugin": "^0.1.16", // 0.1.16
        "copy-webpack-plugin": "^4.0.1", // 4.0.1
        "core-js": "^2.4.1", // 2.4.1
        "css-loader": "^0.28.4", // 0.28.4
        "extract-text-webpack-plugin": "^3.0.0", // 3.0.0
        "file-loader": "^0.11.2", // 0.11.2
        "font-awesome": "^4.7.0", // 4.7.0
        "jquery": "^3.2.1", // 3.2.1
        "lodash": "^4.17.4", // 4.17.4
        "node-sass": "^4.5.3", // 4.5.3
        "resolve-url-loader": "^2.1.0", // 2.1.0
        "sass-loader": "^6.0.6", // 6.0.6
        "style-loader": "^0.18.2", // 0.18.2
        "sweetalert2": "^6.6.6", // 6.6.6
        "webpack": "^3.4.1", // 3.4.1
        "webpack-chunk-hash": "^0.4.0", // 0.4.0
        "webpack-dev-server": "^2.6.1", // 2.6.1
        "webpack-manifest-plugin": "^1.2.1" // 1.2.1
    }
}
userVoice