Management of CSS, Javascript and their naming conventions in MVC 3
Recently I am building a project heavily relies on javascript/jquery. When some of the partial views are rendered, they need to apply some javascripts or CSS styles. Do you have any ideas on an efficient/effective way to manage t开发者_StackOverflowhose files?
I found a need to do this in my own project, because I wanted to be able to have a separate javascript\css file for each view.
What I ended up doing was creating a controller to aggregate the files on the server for me and then send only one css\js file to the browser. The answer is perhaps more intricate than you requested though, so I'll recommend the first part.
You can make an extension method that you can call at the top of each page to add a JS file to a list in the TempData dictionary for the request. You then call a separate method from the Layout that will render any additional links.
This works because the TempData is kept just for the request, and the layout's View is rendered last (after all the views and partials run).
I have a full example of a class here: http://pastebin.com/EUC2fAca but i'm also forming links to my aggregator, so you'll need to modify. The gist is as follows:
public static string JSKey = "pageJSList";
private static void AddToDictionary(HtmlHelper helper, string[] files, string key)
{
if (files == null || files.Length == 0)
return;
TempDataDictionary dict = helper.ViewContext.TempData;
if (!dict.ContainsKey(key))
dict.Add(key, new List<string>());
(dict[key] as List<string>).AddRange(files);
}
private static void InsertToDictionary(HtmlHelper helper, string[] files, string key)
{
if (files == null || files.Length == 0)
return;
TempDataDictionary dict = helper.ViewContext.TempData;
if (!dict.ContainsKey(key))
dict.Add(key, new List<string>());
(dict[key] as List<string>).InsertRange(0, files);
}
public static void AddJS(this HtmlHelper helper, params string[] files)
{
AddToDictionary(helper, files, JSKey);
}
public static void AddJSToTop(this HtmlHelper helper, params string[] files)
{
InsertToDictionary(helper, files, JSKey);
}
public static MvcHtmlString GetJsTagHtml(HtmlHelper helper)
{
var files = helper.ViewContext.TempData[JSKey] as List<string>;
StringBuilder tags = new StringBuilder();
string jsTemplate = "<script type=\"text/javascript\" src=\"/Scripts/{0}\"></script>";
foreach (string file in files)
{
tags.AppendLine(String.Format(jsTemplate, file));
}
return MvcHtmlString.Create(tags.ToString());
}
You'll want the Insert method to run it on the layout because, again, it runs last so you'll want to Insert jquery libraries or other dependencies that should be first on the list.
Your GetJS method should probably return an MvcHtmlString that contains all of the tags you need.
Hope that helps and wasn't too long winded =)
Management of CSS files and JavaScript files and almost any other file depends on your categorization favorites, or in other terms, your taxonomy. I think the better question is, what guidelines should I follow, to make my project become more successful. For example, however you manage and categorize your JavaScript files, try to not have many of'em in a page, as each of'em make a separate HTTP request to the server. Or, try to be as consistent in naming as possible, so that, in future you won't get puzzled by your code. For CSS and JavaScript, I suggest LDSW.
Use webpack to manage your files. A simple webpack setup could look like
# /webpack.config.js
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const postcssPresetEnv = require("postcss-preset-env");
module.exports = (env, argv) => {
const devMode = argv.mode !== "production";
return {
mode: argv.mode,
entry: {
// Main / Shared
'main': './Content/styles/main.scss',
'theme': './Content/styles/theme.scss',
// Pages
'page-home': './Content/styles/pages/home/home.scss',
'page-register': './Content/styles/pages/register/register.scss',
// If we import _register-forms.scss at the top of register.scss,
// there is no need to include it here. That has nothing to do with webpack.
// Components / Partials
'component-search': './Content/styles/components/search/search.scss',
// Javscripts
'client': './Content/client/client.js',
'home': './Content/client/pages/home/index.js',
'component-search': './Content/client/components/search/search.js',
// Got more partial files? Just import { Helper } from './_search-helpers.js' inside
// search.js, and the code will be included.
},
resolve: {
alias: {
// Setup optional aliases
pages: path.resolve(__dirname, 'Content/styles/pages'),
components: path.resolve(__dirname, 'Content/styles/components'),
}
},
output: {
path: path.resolve(__dirname, "Content/dist"),
publicPath: "/css",
filename: devMode ? "js/[name].js" : "js/[name].min.js"
},
... more webpack stuff here.
Then, you don't need to reference all of your scss files in webpack. For example, now you can just import smaller files with this:
# /Content/styles/pages/register/register.scss
@import './_register-form';
@import './_register-layout';
You don't have to include them in your webpack.config.js, because they are pulled into register.scss with the scss @import.
And likewise, in your javascript files you can just import what you need.
# /Content/client/components/search/search.js
import { SearchHelpers } from '_search-helpers';
search.js will now contain everything from _search-helpers.js.
To me, this seems like a logical structure for front-end code in an MVC project.
精彩评论