Wrap all CoffeScript files in a JQuery document re

2019-09-03 10:35发布

I have a number of CoffeeScript files which I concatenate using a Cakefile before converting to Javascript. How do I wrap the concatenated CoffeScript file with a JQuery on document ready function?

For example:

I have the following CoffeScript files each containing a Class:

foo.coffee bar.coffee tea.coffee

To produce the JS file I use the following Cake command to concatente the coffee and produce the JS:

task 'build', 'Build single application file from source files', ->
  appContents = new Array remaining = appFiles.length
  for file, index in appFiles then do (file, index) ->
    fs.readFile "#{file}.coffee", 'utf8', (err, fileContents) ->
      throw err if err
      appContents[index] = fileContents
      process() if --remaining is 0
  process = ->
    fs.writeFile '../assets/js/app.coffee', appContents.join('\n\n'), 'utf8', (err) ->
      throw err if err
      exec 'coffee --compile ../assets/js/app.coffee', (err, stdout, stderr) ->
        throw err if err
        console.log stdout + stderr
        fs.unlink '../assets/js/app.coffee', (err) ->
          throw err if err
          console.log 'Done.'

This produces I nice JS file like so:

// Generated by CoffeeScript 1.3.3
(function() {

   ...all the code...

}).call(this);

What should I do to wrap ..all the code.. in a JQuery on ready function like so:

(function() {

    $(document).ready(function() {
       ...all the code...
    });

}).call(this);

So, basically want is all the concatenated code to execute after the document is ready.

Sub Question Is what I'm asking the correct way to do this? Should I instead wrap each Class contained in each CoffeeScript file in an on document ready function instead?

Any help is greatly appreciated, I've searched how and low for an answer to this with no avail.

Thank you!

2条回答
爷、活的狠高调
2楼-- · 2019-09-03 10:46

The first decision here is whether to use coffeescript's isoliation pattern, which you do. This encapsulates all code of each coffeescript file. You might need to expose some of the code inside, like:

foo.coffee

class Foo
  a: 20
  f: () -> 
      console.log("...")

window.Foo = Foo

Afterwards you can use your exposed code parts in every document, like:

$(document).ready(function() {
   var f = new window.Foo();
});
查看更多
时光不老,我们不散
3楼-- · 2019-09-03 10:53

First things first, the CoffeeScript compiler already has a join command:

-j, --join [FILE]  

Before compiling, concatenate all scripts together in the order they were passed, and write them into the specified file. Useful for building large projects.

Secondly, instead of using $(document).ready(function () { ...} ), you can just pass the function directly to the $() - $(function () { ... });

For your actual problem, there are a few ways you could do it.

Option 1:

Compile the .coffee files using the -b / --bare option, and then manually concatenate a file containing $(function() { and the start and }); at the end (but that's pretty gross).

Options 2:

Use something like exports = window ? this to get the global object, and assign the functionality you wish to run in the jQuery load function to that global object, eg:

FooModule = do ->
  class Foo 
    constructor: (@blah) ->

  init = ->
    blah = new Foo('bar')

  init: init

exports = window ? this
exports.Foo = FooModule

You could then have another file that contains something like the following:

$(->
  Foo.init()
)

Hope one of those options is good?

查看更多
登录 后发表回答