Webpacker: CoffeeScript 2 and JSX

Created on 3 Nov 2017  路  8Comments  路  Source: rails/webpacker

I'm trying to use CoffeeScript 2's new JSX/XML abilities, to no avail. I've tried this in my environment.js file:

environment.loaders.set('csx', { test: /\.csx$/, use: [{loader: 'jsx-loader'}, {loader: 'coffee-loader'}] })

but then the resulting file can't be found to be included/required.

I've also tried (with the 0.9.0 coffee-loader):

const coffeeLoader = environment.loaders.get('coffee'); coffeeLoader.options.transpile = {presets: ['env']};

and had the same non-results. How can I transform Coffeescript into JSX into JS?

It works fine if i do coffeescript --compile --transform *.coffee on the command line, but that's a pain.

Most helpful comment

You need to tell babel-loader to process Coffee files. I have this in my config/webpack/environment.js:

const babelLoader = environment.loaders.get('babel')
babelLoader.test = /\.(coffee|js)(\.erb)?$/

All 8 comments

You need to tell babel-loader to process Coffee files. I have this in my config/webpack/environment.js:

const babelLoader = environment.loaders.get('babel')
babelLoader.test = /\.(coffee|js)(\.erb)?$/

Made it work like this in environment.js:

environment.loaders.set('coffee', {
  test: /\.coffee(\.erb)?$/,
  use: ['babel-loader', 'coffee-loader']
})

If you are using master, you can do something like this:

// Update coffee loader to use coffeescript 2
const babelLoader = environment.loaders.get('babel')
environment.loaders.set('coffee', {
  test: /\.coffee(\.erb)?$/,
  use:  babelLoader.use.concat(['coffee-loader'])
}, { after: 'babel' })

@koops To use CoffeeScript 2's new JSX/XML abilities I had to add coffee to the loader as @renchap suggested but also keep jsx there: coffee|js|jsx.

const babelLoader = environment.loaders.get('babel')
babelLoader.test = /\.(coffee|js|jsx)(\.erb)?$/

Thanks, everyone! (@renchap @gugat)

Just to summarize what has been said above:

  1. Since CoffeeScript 2 outputs ES6, it needs to be transpiled with Babel
  2. babel-loader is already loaded as a dependency of webpacker
  3. Loaders are applied in the reverse order they appear in Webpack config, and to files matching the test attribute. [1]
  4. When in doubt, take a look at all your loaders by adding console.log("debug", environment.loaders) into config/webpack/environment.js and restarting your webpacker-dev-server
  5. Here's a working sample configuration for JS + JSX + CoffeeScript2 + erb
// config/webpack/environment.js
const { environment } = require('@rails/webpacker')
const coffee =  require('./loaders/coffee')
const erb =  require('./loaders/erb')

environment.loaders.append('coffee', coffee)
environment.loaders.append('erb', erb)

const babelLoader = environment.loaders.get('babel')
babelLoader.test = /\.(coffee|js|jsx)(\.erb)?$/

// uncomment when debugging
// console.log("debug", environment.loaders)

module.exports = environment

[1] Thanks @renchap https://github.com/rails/webpacker/issues/859#issuecomment-331854729

@jurajmasar config/webpack/environment.js changes worked for me.
Also, I'm using coffee+vue, remember you still need to follow these instructions to make vue jsx work. https://github.com/vuejs/babel-plugin-transform-vue-jsx#usage

Hi @gtarsia will you want to record this in the docs?

@ytbryan that'd be cool, I'm not sure where to include that though since it's very specific to vue and coffeescript 2. And also the default coffee integration references 1.x version. I created this gist for the moment:
(rails + webpacker + coffeescript 2 + vue + vuex + jsx) from an existing rails project, with proper structure

Is there a place to discuss this? Like an irc channel? Or just a new issue?

Was this page helpful?
0 / 5 - 0 ratings