简体   繁体   中英

Greasemonkey/Javascript preprocessor and build system

I'm writing a moderately complex script for Greasemonkey. Part of it is generating a big blob of HTML and CSS and cramming it into the page. I'd like to keep these HTML and CSS blobs as separate files in my source tree, since:

  • Javascript has no multiline strings, so either I get a huge line, or lots of concatenation, or line continuations. Ugly.
  • The files evolve at different rates, so having them as separate files in Git is notionally better
  • My text editor can set the mode properly when it's not one document embedded in another

Among many other things.

Unfortunately, Greasemonkey scripts are only ever a single script, not a bundle, so I have to inline the HTML and CSS at some point. I'm trying to find a good build system for this workflow. Building for distribution would involve copying from the HTML and CSS into the user script.

My first instinct was to use make the C preprocessor and #include , but this only works on lines, so doing something like:

var panel = document.createElement('div');
panel.innerHTML = '#include "panel.html"';

Doesn't work.

What I'm looking for is something exactly like http://js-preprocessor.com/ , but that doesn't throw a "wrong number of arguments" error when I run it. :P

JavaScript, at least for Firefox (Greasemonkey) does have multi-line strings. So, you can store code in variables without having to futz around with concatenation or \\ chars.

For example, this works in Firefox:

var myPageCodeString = (<><![CDATA[

    <style type="text/css">
        .UpperLeft {
            position:           absolute;
            left:               0;
            top:                0;
            background:         orange;
        }
    </style>
    <script type="text/javascript">
        console.log ("Look at me, Ma! I was data, now I'm JS code!");
    </script>

    <div class="UpperLeft">
        <p>Look at me, Ma!</p>
        <p>I was data, now I'm HTML code!</p>
    </div>

]]></>).toString ();


$("body").append (myPageCodeString);

Try it from the console on a page that has jQuery.

Other than that:

  • If the includes are fixed at "compile" time , use @require and/or @resource .
    If an installed script will be updated in place (versus uninstall then reinstall), be sure to rename or "version" any @require or @resource files, so that GM/FF will update the copies on the user's machine.

    EG, version: @require http://My_Site/MyJs.js
    to: @require http://My_Site/MyJs.js?vers=2 , etc.

  • If the includes are pulled at run time , use cross-domain AJAX, via GM_xmlhttpRequest() to load the code/data.

Hmm, that's a hard question. I guess you considered the @require or @resource-thingies , which includes other documents as annoying (since it only gets downloaded when installing/updating the script).

Another option would be to keep the files on the web and have URLs to them, and fetch them when needed. This won't work for chrome (same-origin policy), but works for greasemonkey/firefox. I'd probably use some raw versioning thing (1 file with relative URLs and versions) and localStorage too then, so the files are cached.

I'm not aware of such a tool, but it doesn't seem to be hard to write in a scripting language. For example, in node.js

var fs = require('fs');

fs.readFile(process.argv[2], "utf-8", function(err, data) {
    console.log(data.toString().replace(/include\s+([\w.]+)/g, function($0, $1) {
        return fs.readFileSync($1).toString().replace(/\n/g, " ");
    }))
})

You can put this in build.js or whatever and call it in your makefile.

Try this one one – @Builder , which among other features supports includes directly from GitHub: https://github.com/electricimp/Builder

Little example

@include "localFile.js"
@include once "github:jquery/jquery/build/release.js@2.2.3"

@set ABC 123

@if ABC > 123
  //
@else
  //
@end

I ended rolling my own in Python. It's not exactly trivial (~50 LOC), thg435, but it does the job. Brock Adams' CDATA multiline string makes it easier.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM