Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebPack + CodeMirror + LoadMode #4838

Closed
hacdias opened this issue Jul 5, 2017 · 11 comments
Closed

WebPack + CodeMirror + LoadMode #4838

hacdias opened this issue Jul 5, 2017 · 11 comments

Comments

@hacdias
Copy link

hacdias commented Jul 5, 2017

Hello!

I'm trying to use Codemirror with LoadMode alongside with WebPack. I thought about having something like:

new CopyWebpackPlugin([
{
    from: path.resolve(__dirname, '../node_modules/codemirror/mode/*/*'),
    to: path.join(config.build.assetsSubDirectory, 'js/codemirror/mode/[name]/[name].js')
}

and then have the CodeMirror to auto load the files but I can't get it to work. When I import 'loadmodule' I get this warning and it doesn't seem to be working:

warning  in ./~/codemirror/addon/mode/loadmode.js
51:6-19 Critical dependency: the request of a dependency is an expression

This is my import section of the file:

import 'codemirror/addons/mode/loadmodule'
import CodeMirror from 'codemirror'

I can use Codemirror and the themes. I'm not just being able to load the modes dynamically and I didn't want to import them at once.

How do I plug loadmode into CodeMirror?

Thanks!

@marijnh
Copy link
Member

marijnh commented Jul 5, 2017

loadMode doesn't really work with static bundlers -- it dynamically loads files on demand using require or script tags. It may be possible to somehow set this up with Webpack's code splitting features, but I have no idea how, and consider that out of the scope of this project.

@marijnh marijnh closed this as completed Jul 5, 2017
@hacdias
Copy link
Author

hacdias commented Jul 5, 2017

Hi @marijnh! Thanks, anyway. If I manage to make it work, I'll just leave a post here and explain how.

@hacdias
Copy link
Author

hacdias commented Jul 5, 2017

So I created something like a wrapper around CodeMirror and instead of importing CodeMirror directly, I import this file:

// Most of the code from this file comes from:
// https://github.com/codemirror/CodeMirror/blob/master/addon/mode/loadmode.js
import * as CodeMirror from 'codemirror'

// Make CodeMirror available globally so the modes' can register themselves.
window.CodeMirror = CodeMirror

if (!CodeMirror.modeURL) CodeMirror.modeURL = '../mode/%N/%N.js'

var loading = {}

function splitCallback (cont, n) {
  var countDown = n
  return function () {
    if (--countDown === 0) cont()
  }
}

function ensureDeps (mode, cont) {
  var deps = CodeMirror.modes[mode].dependencies
  if (!deps) return cont()
  var missing = []
  for (var i = 0; i < deps.length; ++i) {
    if (!CodeMirror.modes.hasOwnProperty(deps[i])) missing.push(deps[i])
  }
  if (!missing.length) return cont()
  var split = splitCallback(cont, missing.length)
  for (i = 0; i < missing.length; ++i) CodeMirror.requireMode(missing[i], split)
}

CodeMirror.requireMode = function (mode, cont) {
  if (typeof mode !== 'string') mode = mode.name
  if (CodeMirror.modes.hasOwnProperty(mode)) return ensureDeps(mode, cont)
  if (loading.hasOwnProperty(mode)) return loading[mode].push(cont)

  var file = CodeMirror.modeURL.replace(/%N/g, mode)

  var script = document.createElement('script')
  script.src = file
  var others = document.getElementsByTagName('script')[0]
  var list = loading[mode] = [cont]

  CodeMirror.on(script, 'load', function () {
    ensureDeps(mode, function () {
      for (var i = 0; i < list.length; ++i) list[i]()
    })
  })

  others.parentNode.insertBefore(script, others)
}

CodeMirror.autoLoadMode = function (instance, mode) {
  if (CodeMirror.modes.hasOwnProperty(mode)) return

  CodeMirror.requireMode(mode, function () {
    instance.setOption('mode', instance.getOption('mode'))
  })
}

export default CodeMirror

@tony
Copy link

tony commented Jul 31, 2017

@hacdias I'm interested in seeing what the entirety (to the extent possible) of what your webpack looks like when it loads codemirror / dependencies. Is that something you're willing to share?

I've even looked through GH search, Having quite the struggle finding an up to date webpack config example with CodeMirror.

Best

@hacdias
Copy link
Author

hacdias commented Aug 1, 2017

Hey @tony! I'm using it on this project. It's all open source.

@tony
Copy link

tony commented Aug 2, 2017

Way to go posting that 👍 @hacdias

@Jocs
Copy link

Jocs commented Nov 21, 2017

@hacdias Have you solved this problem? i also run into this issue.

@hacdias
Copy link
Author

hacdias commented Nov 21, 2017

Hey @Jocs! I used the function above ^^

@Jocs
Copy link

Jocs commented Nov 22, 2017

@hacdias 3q
😄

@chinchang
Copy link

Thanks @hacdias 👍

@AndersDeath
Copy link

@hacdias Thank you very much! You saved a little time of my life!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants