1

MVC4 で Bundle と Minification を試していたところ、興味深い問題に遭遇しました。私は Coffeescript を使用していますが、この@Scripts.Render()メソッドのように機能する Render ヘルパーが必要です。

たとえば、次のバンドル構成があるとします。

new ScriptBundle("~/bundle/appfiles").Include(
    "~/Scripts/app/sample.js",
    "~/Scripts/app/myApp.js");

cshtml では@Scripts.Render()、web.config のデバッグ設定に基づいて異なる結果が得られます。debug が true の場合、ファイルごとに 1 つのスクリプト タグを取得します。それ以外の場合は、バンドルされて縮小された js を返す単一のスクリプト タグを取得します。これで問題ありません。

ここで、Coffeescripts で同じことをしたいと仮定しましょう。次のようなバンドルを作成します。

new Bundle("~/bundle/appfiles", new CoffeeBundler(), new JsMinify()).Include(
    "~/Scripts/app/sample.coffee",
    "~/Scripts/app/myApp.coffee");

問題は@Scripts.Render()、デバッグ中にファイルごとに 1 つのスクリプトを使用すると、まったく変換されないことです。私ができる唯一の用途はこれです:

<script type="text/javascript" src="@(BundleTable.Bundles.ResolveBundleUrl("~/bundle/appfiles"))"></script>

しかし、これは、デバッグモードであっても、すべてをまとめてから縮小します。もちろん、これは私が望んでいるものではありません。

Coffee.Render()Scripts に似たヘルパーを作成しようとしましたが、System.Web.Optimization アセンブリの内部にある AssetManager クラスを使用します。

これをきれいな方法で行う方法についてアイデアがあるかどうか疑問に思っていました (つまり、利用可能なパブリック クラスを使用し、AssetManager コード全体をコピー アンド ペーストせず、バンドルを作成するときに派手な Directory.EnumerateFiles を実行しません)。

ありがとう!

PS: より迅速な解決策は、Mindscape Workbench を使用して、生成された js ファイルをバンドルすることであることを知っています。私は、フレームワークが持っているものを使用するものを探しています。おそらく、人々がインストールしないツールをインストールするようにチームに指示する必要もありません。お気に入り...

4

2 に答える 2

1

結局、私はこのためのHtmlHelperソリューションを選びました。まだ初期段階ですが、思い通りに動作しています。とりあえずブログ投稿で詳しく説明しています。

ブログが失われた場合の完全なヘルパーコードは次のとおりです...

public static class HtmlHelperExtensions
{
    public static MvcHtmlString RenderCoffeeBundle(this HtmlHelper htmlHelper, string virtualPath)
    {
        if (String.IsNullOrEmpty(virtualPath))
            throw new ArgumentException("virtualPath must be defined", "virtualPath");

        var list = GetPathsList(virtualPath);

        //TODO: Nice and cleaner EliminateDuplicatesAndResolveUrls(list);

        var stringBuilder = new StringBuilder();
        foreach (string path in list)
        {
            stringBuilder.Append(RenderScriptTag(path));
            stringBuilder.Append(Environment.NewLine);
        }
        return MvcHtmlString.Create(stringBuilder.ToString());
    }

    private static IEnumerable<string> GetPathsList(string virtualPath)
    {
        var list = new List<string>();

        if (BundleResolver.Current.IsBundleVirtualPath(virtualPath))
        {
            if (!BundleTable.EnableOptimizations)
            {
                foreach (var path in BundleResolver.Current.GetBundleContents(virtualPath))
                {
                    var bundlePath = "~/autoBundle" + ResolveVirtualPath(path.Replace("coffee", "js"));
                    BundleTable.Bundles.Add(new Bundle(bundlePath, new CoffeeBundler()).Include(path));
                    // TODO: Get the actual CustomTransform used in the Bundle
                    // rather than forcing "new CoffeeBundler()" like here
                    list.Add(bundlePath);
                }
            }
            else
                list.Add(BundleResolver.Current.GetBundleUrl(virtualPath));
        }
        else
            list.Add(virtualPath);
        return list.Select(ResolveVirtualPath).ToList();
    }

    private static string RenderScriptTag(string path)
    {
        return "<script src=\"" + HttpUtility.UrlPathEncode(path) + "\"></script>";
    }

    private static string ResolveVirtualPath(string virtualPath)
    {
        return VirtualPathUtility.ToAbsolute(virtualPath);;
    }
}
于 2013-01-19T17:10:26.450 に答える
0

申し訳ありませんが、正確な質問に対応していませんが、投稿の最後で PS と話したいと思います。

現時点では、「ツールがない」という話はないと思いますが、「フレームワークが備えているものを使用する」という意見には同意します。

そのために、TypeScript を使用することを強くお勧めします。(CoffeeScript のように) 新しい言語を学ぶ必要はありませんが、強く型付けされたバージョンの JavaScript が提供され、c# のように (型検証などを使用して) より多くのことを使用できます。

いくつかのチュートリアルを完了するには、20 分かかります。

http://www.typescriptlang.org/Playground/

または、さらに良いことに、秋の BUILD セッションをご覧ください。

http://channel9.msdn.com/Events/Build/2012/3-012

ところで...これがあなたが望んでいる方向ではない場合でも、心配はいりません...多くの開発者は、オプションとしての TypeScript についてまだ知らないだけです。

これが、チームのために物事を簡素化するための探求に役立つことを願っています.

乾杯。

于 2013-01-18T16:05:07.923 に答える