Linking JavaScript Libraries in User Controls

后端 未结 2 554
攒了一身酷
攒了一身酷 2020-12-06 03:06

I have been using ASP.NET MVC for six months or so and have been checking out the Nerd Dinner example created by those Microsoft guys. One thing I noticed they did when ena

相关标签:
2条回答
  • 2020-12-06 03:40

    In my website, www.trailbehind.com, we have a set of javascript files that belong on all pages. And then some pages include additional libraries.

    For the JS files that all pages uses (there are a couple dozen files), we concatenate them and minify them on build.

    There is a flag in our settings file that says whether to use the concatenated javascript or the separate files on build. This is critical so that you can debug the javascript on dev, but use the small, single-file javascript on production.

    Here is our python code to combine and minify:

    import os
    import thetrailbehind.lib.jsmin as jsmin
    
    JS_FILES = [  'lib/json2.js',
                  'lib/markermanager.js',
                  'lib/labeledmarker.js',
                  'lib/rsh/rsh.js', 
                  'lib/showdown.js',
                  'lib/yui.js',
                  'lib/dragzoom.js',
                  'gen/attribute_data.js', 
                  'gen/national-parks.js', 
                  'Widgets/CommentsWidget.js', 
                  'Widgets/Search.js', 
                  'Widgets/MenuWidget.js', 
                  'Widgets/PhotoWidget.js', 
                  'Widgets/ReportList.js', 
                  'Widgets/help.js', 
                  'attributes.js', 
                  'rsh.js', 
                  'map.js', 
                  'mapcontrols.js',
                  'markers.js',
                  'amazon.js',
                  'plan_trip.js', 
                  'init.js',]
    
    
    def concat(files, base_path, all_file, all_file_min):
      if os.path.exists(base_path + all_file):
        lasttime = os.path.getmtime(base_path + all_file)
      else:
        lasttime = 0
      out_of_date = False
      for file in files:
        if os.path.getmtime(base_path + file) > lasttime:
          out_of_date = True
          break
      if out_of_date:
        outfile = open(base_path + all_file, 'w')
        for file in files:
          outfile.write(open(base_path + file).read())
          outfile.write("\n")
        outfile.close()
    
        alljs = open(base_path + all_file)
        allminjs = open(base_path + all_file_min, "w+")
        jsmin.JavascriptMinify().minify(alljs, allminjs)
        alljs.close()
        allminjs.close()
    
    
    
    def main():
      concat(JS_FILES, '/home/wibge/thetrailbehind/media/javascript/', 'gen/all.js', 'gen/all.min.js')
    
    
    if __name__ == "__main__":
      main()
    

    And here is the Django/HTML template where we switch:

    {% if use_all_js %}
      script type=text/javascript src=/site_media/javascript/gen/all.min.js> 
    {% else %}
      script type="text/javascript" src="/site_media/javascript/rsh.js">
      script type="text/javascript" src="/site_media/javascript/amazon.js">
      script type="text/javascript" src="/site_media/javascript/map.js">  
      A BUNCH OF SEPARATE INCLUDES...etc
    {% endif %}
    
    0 讨论(0)
  • 2020-12-06 03:44

    I would definitely advise against putting them inside partials for exactly the reason you mention. There is a high chance that one view could pull in two partials that both have references to the same js file. You've also got the performance hit of loading js before loading the rest of the html.

    I don't know about best practice but I choose to include any common js files inside the masterpage and then define a separate ContentPlaceHolder for some additional js files that are specific to a particular or small number of views.

    Here's an example master page - it's pretty self explanatory.

    <%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>
    <head runat="server">
        ... BLAH ...
        <asp:ContentPlaceHolder ID="AdditionalHead" runat="server" />
        ... BLAH ...
        <%= Html.CSSBlock("/styles/site.css") %>
        <%= Html.CSSBlock("/styles/ie6.css", 6) %>
        <%= Html.CSSBlock("/styles/ie7.css", 7) %>
        <asp:ContentPlaceHolder ID="AdditionalCSS" runat="server" />
    </head>
    <body>
        ... BLAH ...
        <%= Html.JSBlock("/scripts/jquery-1.3.2.js", "/scripts/jquery-1.3.2.min.js") %>
        <%= Html.JSBlock("/scripts/global.js", "/scripts/global.min.js") %>
        <asp:ContentPlaceHolder ID="AdditionalJS" runat="server" />
    </body>
    

    Html.CSSBlock & Html.JSBlock are obviously my own extensions but again, they are self explanatory in what they do.

    Then in say a SignUp.aspx view I would have

    <asp:Content ID="signUpContent" ContentPlaceHolderID="AdditionalJS" runat="server">
        <%= Html.JSBlock("/scripts/pages/account.signup.js", "/scripts/pages/account.signup.min.js") %>
    </asp:Content>
    

    HTHs, Charles

    Ps. I would agree with Andrew in saying that any common JS that is defined directly inside the master page should be concatenated and minified.

    EDIT: My implementation of .JSBlock(a, b) as requested

    public static MvcHtmlString JSBlock(this HtmlHelper html, string fileName)
    {
        return html.JSBlock(fileName, string.Empty);
    }
    
    public static MvcHtmlString JSBlock(this HtmlHelper html, string fileName, string releaseFileName)
    {
        if (string.IsNullOrEmpty(fileName))
            throw new ArgumentNullException("fileName");
    
        string jsTag = string.Format("<script type=\"text/javascript\" src=\"{0}\"></script>",
                                     html.MEDebugReleaseString(fileName, releaseFileName));
    
        return MvcHtmlString.Create(jsTag);
    }
    

    And then where the magic happens...

        public static MvcHtmlString MEDebugReleaseString(this HtmlHelper html, string debugString, string releaseString)
        {
            string toReturn = debugString;
    #if DEBUG
    #else
            if (!string.IsNullOrEmpty(releaseString))
                toReturn = releaseString;
    #endif
            return MvcHtmlString.Create(toReturn);
        }
    
    0 讨论(0)
提交回复
热议问题