मैं एक स्पष्ट ScriptBundle ऑर्डर कैसे शामिल कर सकता हूं?


91

मैं MVC4 System.Web.Optimization 1.0 ScriptBundle फीचर को आज़मा रहा हूँ ।

मेरे पास निम्न कॉन्फ़िगरेशन है:

public class BundleConfig
{
    public static void RegisterBundles(BundleCollection bundles)
    {
        // shared scripts
        Bundle canvasScripts =
            new ScriptBundle(BundlePaths.CanvasScripts)
                .Include("~/Scripts/modernizr-*")
                .Include("~/Scripts/json2.js")
                .Include("~/Scripts/columnizer.js")
                .Include("~/Scripts/jquery.ui.message.min.js")
                .Include("~/Scripts/Shared/achievements.js")
                .Include("~/Scripts/Shared/canvas.js");
        bundles.Add(canvasScripts);
    }
}

और निम्नलिखित दृश्य:

<script type="text/javascript" src="@Scripts.Url(BundlePaths.CanvasScripts)"></script>

जहां BundlePaths.CanvasScriptsहै "~/bundles/scripts/canvas"। यह इसका प्रतिपादन करता है:

<script type="text/javascript" src="/bundles/scripts/canvas?v=UTH3XqH0UXWjJzi-gtX03eU183BJNpFNg8anioG14_41"></script>

अब तक बहुत अच्छा है, सिवाय ~/Scripts/Shared/achievements.jsबंडल वाले स्रोत में पहली स्क्रिप्ट। यह हर लिपि पर निर्भर करता है, जिसमें यह शामिल है ScriptBundleमैं यह कैसे सुनिश्चित कर सकता हूं कि यह उस आदेश का सम्मान करता है जिसमें मैं बंडल में बयान शामिल करता हूं?

अपडेट करें

यह अपेक्षाकृत नया ASP.NET MVC 4 अनुप्रयोग था, लेकिन यह ऑप्टिमाइज़ेशन फ्रेमवर्क प्री रिलीज़ पैकेज का संदर्भ दे रहा था। मैंने इसे हटा दिया और http://nuget.org/packages/Microsoft.AspNet.Web.Optimization से RTM पैकेज जोड़ा । RTM संस्करण के साथ debug = true में web.config, @Scripts.Render("~/bundles/scripts/canvas")अलग-अलग स्क्रिप्ट टैग को सही क्रम में प्रस्तुत करता है।

Web.config में debug = false के साथ, संयुक्त स्क्रिप्ट में उपलब्धियां हैं। पहले स्क्रिप्ट, लेकिन चूंकि इसकी फ़ंक्शन परिभाषा (ऑब्जेक्ट कंस्ट्रक्टर) जिसे बाद में कहा जाता है, यह त्रुटि के बिना चलता है। शायद minifier निर्भरता का पता लगाने के लिए काफी स्मार्ट है?

मैंने यह भी IBundleOrdererलागू करने की कोशिश की कि डारिन दिमित्रोव ने आरटीएम के साथ दोनों डिबग विकल्पों के साथ सुझाव दिया और इसने समान व्यवहार किया।

इसलिए कीमा बनाया हुआ संस्करण मेरे द्वारा अपेक्षित क्रम में नहीं है, लेकिन यह काम करता है।

जवाबों:


18

मैं RTM बिट्स पर इस व्यवहार को नहीं देख रहा हूं, क्या आप Microsoft ASP.NET वेब ऑप्टिमाइज़ेशन फ्रेमवर्क 1.0.0 बिट्स का उपयोग कर रहे हैं: http://nuget.org/packages/Microsoft.AspNet.Web.Optimization ?

मैंने एक नए MVC4 इंटरनेट एप्लिकेशन वेबसाइट के आधार पर, आपके नमूने के लिए एक समान रिप्रो का उपयोग किया।

मैंने बंडलकॉन्फ़िग में जोड़ा।

        Bundle canvasScripts =
            new ScriptBundle("~/bundles/scripts/canvas")
                .Include("~/Scripts/modernizr-*")
                .Include("~/Scripts/Shared/achievements.js")
                .Include("~/Scripts/Shared/canvas.js");
        bundles.Add(canvasScripts); 

और फिर डिफ़ॉल्ट इंडेक्स पेज में, मैंने जोड़ा:

<script src="@Scripts.Url("~/bundles/scripts/canvas")"></script>

और मैंने सत्यापित किया कि बंडल के लिए मिनीकृत जावास्क्रिप्ट में, उपलब्धियों की सामग्री। जेएस आधुनिकीकरण के बाद थी ...


मैंने 1.0 संस्करण में अपग्रेड किया। मेरा अद्यतन प्रश्न देखें। उपलब्धियों की सामग्री.जेएस पहले लघु संस्करण में शामिल हैं, लेकिन यह बाद में नामक एक समारोह के बाद से काम करता है।
jrummell

114

आप एक कस्टम बंडल ऑर्डरर ( IBundleOrderer) लिख सकते हैं जो यह सुनिश्चित करेगा कि बंडल आपके द्वारा पंजीकृत किए गए क्रम में शामिल हैं:

public class AsIsBundleOrderer : IBundleOrderer
{
    public virtual IEnumerable<FileInfo> OrderFiles(BundleContext context, IEnumerable<FileInfo> files)
    {
        return files;
    }
}

और फिर:

public class BundleConfig
{
    public static void RegisterBundles(BundleCollection bundles)
    {
        var bundle = new Bundle("~/bundles/scripts/canvas");
        bundle.Orderer = new AsIsBundleOrderer();
        bundle
            .Include("~/Scripts/modernizr-*")
            .Include("~/Scripts/json2.js")
            .Include("~/Scripts/columnizer.js")
            .Include("~/Scripts/jquery.ui.message.min.js")
            .Include("~/Scripts/Shared/achievements.js")
            .Include("~/Scripts/Shared/canvas.js");
        bundles.Add(bundle);
    }
}

और आपके विचार में:

@Scripts.Render("~/bundles/scripts/canvas")

10
यह काम करना चाहिए, लेकिन यह भी अनावश्यक होना चाहिए, क्योंकि डिफ़ॉल्ट ऑर्डरर में आम तौर पर शामिलों के आदेश का सम्मान किया जाता है (यह केवल शीर्ष पर कुछ विशेष फाइलों को बढ़ावा देता है, यानी jquery, reset.css / normalize.css, आदि)। यह उपलब्धियों को बढ़ावा नहीं देना चाहिए।
हाओ कुंग

1
@flipdoubt रेपो के साथ यहां एक समस्या दर्ज करें: aspnetoptimization.codeplex.com/workitem/list/advanced
हाओ कुंग

1
यह सही काम करता है, धन्यवाद! मैं हालांकि सहमत हूं, यह आवश्यक नहीं होना चाहिए।
CBarr

2
यह मेरे लिए काम करता है। जब यह stackoverflow.com/questions/17367736/ के अनुसार बूटस्ट्रैप पर jqueryui को बढ़ावा दे रहा था, तो मुझे इसकी आवश्यकता है।
सेथरन

1
@ हाओ कुंग हम डायरेक्टरी में फाइलों को ऑर्डर कर सकते हैं ?
शैजुत

52

धन्यवाद डारिन। मैंने एक एक्सटेंशन विधि जोड़ी है।

internal class AsIsBundleOrderer : IBundleOrderer
{
    public virtual IEnumerable<FileInfo> OrderFiles(BundleContext context, IEnumerable<FileInfo> files)
    {
        return files;
    }
}

internal static class BundleExtensions
{
    public static Bundle ForceOrdered(this Bundle sb)
    {
        sb.Orderer = new AsIsBundleOrderer();
        return sb;
    }
}

प्रयोग

bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                    "~/Scripts/jquery-{version}.js",
                    "~/Scripts/jquery-migrate-{version}.js",

                    "~/Scripts/jquery.validate.js",
                    "~/Scripts/jquery.validate.messages_fr.js",
                    "~/Scripts/moon.jquery.validation-{version}.js",

                    "~/Scripts/jquery-ui-{version}.js"
                    ).ForceOrdered());

9
बहुत सुंदर! : डी अभी मैं परिवर्तन करना पड़ा FileInfoके लिए BundleFileइंटरफ़ेस विधि हस्ताक्षर में। उन्होंने इसे बदल दिया।
लेनियल मैकाफेर्री

हाँ, उन्होंने इसे प्रीलेरेज़ संस्करण में बदल दिया है जो
सॉफ्टलिओन

थोड़ा ऑफ-टॉपिक: क्या किसी को इस BundleFileवर्ग की अधिक जानकारी है ? एम्बेडेड संसाधनों को बंडल करने के लिए, मैं इसे बनाने की कोशिश कर रहा हूं और इसके निर्माता में एक (ठोस बच्चे) VirtualFileपैरामीटर की आवश्यकता है ।
सुपरजोस

मेरे पास एक ही सवाल है, मुझे तत्काल बंडल की जरूरत है, लेकिन पता नहीं कैसे
रुई

2
@superjos मुझे पता है कि यह पुराना है, लेकिन मैं किसी और की समस्या होने पर जवाब दूंगा। यह System.Web.Optimization का हिस्सा है।
Talon

47

MVC 5 (बंडलफाइल बनाम फाइलइन्फो) में बदलाव को संभालने के लिए सॉफ्टलिओन द्वारा दिए गए उत्तर को अपडेट किया गया।

internal class AsIsBundleOrderer : IBundleOrderer
{
    public virtual IEnumerable<BundleFile> OrderFiles(BundleContext context, IEnumerable<BundleFile> files)
    {
        return files;
    }
}

internal static class BundleExtensions
{
    public static Bundle ForceOrdered(this Bundle sb)
    {
        sb.Orderer = new AsIsBundleOrderer();
        return sb;
    }
}

उपयोग:

    bundles.Add(new ScriptBundle("~/content/js/site")
        .Include("~/content/scripts/jquery-{version}.js")
        .Include("~/content/scripts/bootstrap-{version}.js")
        .Include("~/content/scripts/jquery.validate-{version}")
        .ForceOrdered());

मुझे धाराप्रवाह सिंटैक्स का उपयोग करना पसंद है, लेकिन यह एक एकल विधि कॉल के साथ भी काम करता है और सभी स्क्रिप्ट पैरामीटर के रूप में पारित हो जाते हैं।


2
MVC में काम करता है 5. धन्यवाद
पास्कल कार्मोनी

4
अति उत्कृष्ट। यह एमएस imho द्वारा शामिल किया जाना चाहिए
एंजेलो

वेब फॉर्म में भी एक आकर्षण की तरह काम करता है ... मूल रूप से इसे सभी नवीनतम संस्करणों के लिए ठीक काम करना चाहिए!
सनी शर्मा

बहुत साफ और सरल उपाय। बहुत बहुत धन्यवाद।
बनर्जी १०'१६

5

आपको बंडलकॉलशन की मदद से ऑर्डर सेट करने में सक्षम होना चाहिए। FileSetOrderList। इस ब्लॉग पोस्ट पर एक नज़र डालें: http://weblogs.asp.net/imranbaloch/archive/2012/09/30/hidden-options-of-asp-net-bundling-and-minification.aspx । आपके उदाहरण में कोड कुछ इस तरह होगा:

BundleFileSetOrdering bundleFileSetOrdering = new BundleFileSetOrdering("js");
bundleFileSetOrdering.Files.Add("~/Scripts/modernizr-*");
bundleFileSetOrdering.Files.Add("~/Scripts/json2.js");
bundleFileSetOrdering.Files.Add("~/Scripts/columnizer.js");
bundleFileSetOrdering.Files.Add("~/Scripts/jquery.ui.message.min.js");
bundleFileSetOrdering.Files.Add("~/Scripts/Shared/achievements.js");
bundleFileSetOrdering.Files.Add("~/Scripts/Shared/canvas.js");
bundles.FileSetOrderList.Add(bundleFileSetOrdering);

1

आपको कैसेट http://getcassette.net/ का उपयोग करने पर विचार करना चाहिए। यह प्रत्येक फ़ाइल के अंदर पाए जाने वाले स्क्रिप्ट संदर्भों के आधार पर स्क्रिप्ट निर्भरता के ऑटो डिटेक्शन का समर्थन करता है।

यदि आप एमएस वेब ऑप्टिमाइज़ेशन सॉल्यूशन से चिपके रहना पसंद करते हैं, लेकिन स्क्रिप्ट संदर्भों के आधार पर स्क्रिप्ट की व्यवस्था करने का विचार आपको मेरे ब्लॉग पोस्ट http://blogs.microsoft.co.il/oric/2013/12/12/27/building-single पर पढ़ना चाहिए -page आवेदन-बंडल-orderer /


1

@ डारिन दिमित्रोव का जवाब मेरे लिए पूरी तरह से काम करता है, लेकिन मेरा प्रोजेक्ट VB में लिखा गया है, इसलिए यहाँ उसका जवाब VB में बदल दिया गया है

Public Class AsIsBundleOrderer
    Implements IBundleOrderer

    Public Function IBundleOrderer_OrderFiles(ByVal context As BundleContext, ByVal files As IEnumerable(Of FileInfo)) As IEnumerable(Of FileInfo) Implements IBundleOrderer.OrderFiles
        Return files
    End Function
End Class

इसके प्रयेाग के लिए:

Dim scriptBundleMain = New ScriptBundle("~/Scripts/myBundle")
scriptBundleMain.Orderer = New AsIsBundleOrderer()
scriptBundleMain.Include(
    "~/Scripts/file1.js",
    "~/Scripts/file2.js"
)
bundles.Add(scriptBundleMain)

मुझे यह त्रुटि मिलती रहती है: Class 'AsIsBundleOrderer' must implement 'Function OrderFiles(context as ....)' for interface 'System.Web.Optimization.IBundleOrderer'कोई विचार?
मार्क पिज़्ज़ाक - त्रिलोन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.