Skip to content
This repository has been archived by the owner on Sep 17, 2018. It is now read-only.

Inserting a string from external file inside a generated js file brings an undesired newline #11

Closed
augusto-herrmann opened this issue Oct 25, 2012 · 7 comments

Comments

@augusto-herrmann
Copy link
Contributor

Description

We're trying to build a js file that has a string whose content comes from another external file (e.g. for inserting css styles dynamically into the DOM). The problem is, in Javascript, strings must be contained in a single line, and when assetgen imports the file, a newline gets added at the end.

How to reproduce

Take any file (in this example, assets/single-line.css) that has a single line (contains no newlines) in it. Use the following yaml configuration file to generate a new .js file (in this case, runtime-styles.js). For the record, we're using Linux (in case the newline stuff makes any difference).

# newline-bug.yaml:

generate:

- runtime-styles.js:
    source:
      - raw: "insert_css('"
      - assets/single-line.css
      - raw: "');" # closing function
    compress: false

js.uglify.bin: uglifyjs
output.directory: build
output.hashed: false

The generated runtime-styles.js file will have to lines. An unwanted newline will appear before the closing part (i.e. ");").

@tav
Copy link
Owner

tav commented Oct 25, 2012

Are you sure that assets/single-line.css doesn't have a newline at the end of it? That's the only explanation I can see why there might be an unwanted newline in the generated file. Some text editors automatically put in a closing newline, e.g. with nano you have to explicitly call nano -L to stop it from inserting newlines.

@nitaibezerra
Copy link

Hi Tav,

I work with Augusto.
Indeed there is a invisible newline at the end of it.
But, even so it's a comon use case to insert the content of a file into a
JavaScript string. There should be some easy way to handle that.

Whay not create a specific parameter that says to Assentgem to consider the
content of a file is a string. In other words, it would ignore newlines if
any exist.

cheers,
Nitai

On Thu, Oct 25, 2012 at 11:10 AM, tav notifications@github.com wrote:

Are you sure that assets/single-line.css doesn't have a newline at the
end of it? That's the only explanation I can see why there might be an
unwanted newline in the generated file. Some text editors automatically put
in a closing newline, e.g. with nano you have to explicitly call nano -Lto stop it from inserting newlines.


Reply to this email directly or view it on GitHubhttps://github.com//issues/11#issuecomment-9776796.

@tav
Copy link
Owner

tav commented Oct 25, 2012

Hey Nitai,

As it is, it's left up to the developer to decide whether they want a newline or not by putting them in or leaving them out of the source files that they are including. I think that's the simplest approach and provides no surprises since it outputs exactly what is provided as input.

However, your use case suggested that there might be value in having a js.template config value. So I just implemented it using the Mako templating language. Once you've upgraded assetgen to the new 0.3.2 release, you can achieve what you want with:

generate:

- runtime-styles.js:
    source:
      - assets/single-line.css
    compress: false
    template: |
        insert_css(${source|trim,jsliteral});

js.uglify.bin: uglifyjs
output.directory: build
output.hashed: false

The trim filter strips the newlines for you and I also added a jsliteral filter to quote the source properly as a JavaScript string. I hope that satisfies your needs. Let me know what you think. Thanks.

@augusto-herrmann
Copy link
Contributor Author

Hi, Tav!

Thanks for implementing this so quickly! This solution works as desired.

However, it's unclear what the expected behavior should be when we have more than one source file. As experimented, it seems that the ${source} parameter inside the Mako template applies the content of the first source file. Example:

generate:

- composite.js:
    source:
      - assets/some-content.html
      - assets/behavior.coffee
      - raw: "})();"
    template: |
        (function(){var htmlContent = '${source|trim,jsliteral}';

This works, but it probably should be explicit, should you have more than one source file, don't you think so?

@tav
Copy link
Owner

tav commented Oct 25, 2012

Ah, my bad, should have been clearer on the usage. It applies the template to every source file (i.e. not raw strings) which is not processed in any way, i.e. not CoffeeScript/TypeScript files. And, oh, it only works when source maps are disabled.

Hope that makes sense?

@augusto-herrmann
Copy link
Contributor Author

Thanks! I've updated the example in the README so people can see and use this new feature. Even though at some point I think we should have a full blown documentation (e.g. on readthedocs.org, using Sphinx). I don't have experience with that yet, but this could be an excuse to learn. :)

@tav
Copy link
Owner

tav commented Oct 26, 2012

Thanks again and, yeah, proper documentation would be very cool. If you are up for it, that would be fantastic!

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

No branches or pull requests

3 participants