javascript 使用 node.js 在生产模式下缩小脚本/CSS
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14841320/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Minify Scripts/CSS in production mode with node.js
提问by Christian
I have a web app that runs in node. All the (client) Javascript/CSS files are not minified at the moment to make it easier to debug.
我有一个在 node.js 中运行的网络应用程序。所有(客户端)Javascript/CSS 文件目前都没有缩小,以便于调试。
When I am going into production, I would like to minify these scripts. It would be nice to have something like:
当我进入生产环境时,我想缩小这些脚本。有这样的东西会很好:
node app.js -production
node app.js -production
How do I serve the minified version of my scripts without changing the script tags in my html files? There should be something like: if I am in production, use these 2 minified(combined) scripts, else use all my unminified scripts..
如何在不更改 html 文件中的脚本标签的情况下提供脚本的缩小版本?应该是这样的:如果我在生产中,使用这 2 个缩小(组合)脚本,否则使用我所有未缩小的脚本..
Is this possible? Maybe I am thinking too complicated?
这可能吗?可能是我想的太复杂了?
回答by Golo Roden
You might be interested in Piler. It's a Node.js module that delivers all the JavaScript (and CSS) files you specify as usual when in debug mode, but concatenated and minified when in production mode.
您可能对Piler感兴趣。它是一个 Node.js 模块,可提供您在调试模式下照常指定的所有 JavaScript(和 CSS)文件,但在生产模式下进行连接和缩小。
As a special feature, you can force CSS updates via Socket.io in real-time to appear in your browser (called "CSS Live Updated" in Piler), which is quite awesome :-).
作为一项特殊功能,您可以通过 Socket.io 实时强制 CSS 更新出现在您的浏览器中(在 Piler 中称为“CSS Live Updated”),这非常棒:-)。
The trick is that inside your template you only have placeholders for the script
and link
elements, and Piler renders these elements at runtime - as single elements in debug mode, and as a dynamically generated single element in production mode.
诀窍在于,在您的模板中,您只有script
和link
元素的占位符,而 Piler 在运行时渲染这些元素——在调试模式下作为单个元素,在生产模式下作为动态生成的单个元素。
This way you can forget about creating concatenated and minified versions of your assets manually or using a build tool, it's just there at runtime, but you always have the separated, full versions when developing and debugging.
通过这种方式,您可以忘记手动或使用构建工具创建资产的串联和缩小版本,它只是在运行时存在,但在开发和调试时您始终拥有分离的完整版本。
回答by Pascal Belloncle
you could use 2 separate locations for your static files
您可以为静态文件使用 2 个单独的位置
Here's some express code:
这是一些快速代码:
if (process.env.MODE === "production") {
app.use(express['static'](__dirname + '/min'));
} else {
app.use(express['static'](__dirname + '/normal'));
}
and start node with
并开始节点
MODE=production node app.js
Furthermore, if you don't want to duplicate all your files, you could take advantage of the fact that express static router stops at the first file, and do something like this instead:
此外,如果您不想复制所有文件,您可以利用 express 静态路由器在第一个文件处停止的事实,并执行以下操作:
if (process.env.MODE === "production") {
app.use(express['static'](__dirname + '/min')); // if minized version exists, serves it
}
app.use(express['static'](__dirname + '/normal')); // fallback to regular files
Using the same name for minimized or not is going to cause problem with browser caching, though.
但是,对于最小化与否使用相同的名称会导致浏览器缓存出现问题。
回答by Christian
I want to share my final solution with you guys.
我想与你们分享我的最终解决方案。
I use JSHTML for Express (enter link description here)
我使用 JSHTML for Express(在此处输入链接描述)
In my main node file I use a special route:
在我的主节点文件中,我使用了一个特殊的路由:
app.get('/**:type(html)', function (req, res, next) {
var renderingUrl = req.url.substring(1, req.url.lastIndexOf("."));
//TODO: Find a better solution
try{
var assetUrl = req.url.substring(req.url.lastIndexOf("/") + 1, req.url.lastIndexOf("."));
var assets = config.getResourceBundle(assetUrl);
assets.production = config.getEnviroment() === "production";
res.locals(assets);
res.render(renderingUrl);
}catch(e){
res.redirect("/");
}
});
As you can see, I get my assets from config.getResourceBundle. This is a simply function:
如您所见,我从 config.getResourceBundle 获取我的资产。这是一个简单的函数:
exports.getResourceBundle = function(identifier){
switch(enviroment){
case "development":
return devConfig.getResourceBundle(identifier);
case "production":
return prodConfig.getResourceBundle(identifier);
default:
return devConfig.getResourceBundle(identifier);
}
}
And finally an example for an asset file collection is here:
最后一个资产文件集合的例子在这里:
exports.getResourceBundle = function (identifier) {
return resourceBundle[identifier];
};
resourceBundle = {
index:{
cssFiles:[
"resources/dev/css/login.css",
"resources/dev/css/logonDlg.css",
"resources/dev/css/footer.css"
],
jsFiles:[
"resources/dev/js/lib/jquery/jquery.183.js",
"resources/dev/js/utilities.js",
"resources/dev/js/lib/crypto.3.1.2.js"
]
},
register:{
cssFiles:[
"resources/dev/css/login.css",
"resources/dev/css/modalDialog.css",
"resources/dev/css/footer.css"
],
jsFiles:[
"resources/dev/js/lib/jquery/jquery.183.js",
"resources/dev/js/utilities.js",
"resources/dev/js/lib/crypto.3.1.2.js",
"resources/dev/js/lib/jquery.simplemodal.js",
"resources/dev/js/xfiles.register.js"
]
}
(...)
I have 2 folders. dev / prod. grunt will copy the minified files into prod/.. and deletes the files from dev/... And if the NODE_ENV variable is set to production, I will ship the minified versions of my scripts/css. I think this is the most elegant solution at the moment.
我有 2 个文件夹。开发/生产。grunt 会将缩小的文件复制到 prod/.. 并从 dev/ 中删除文件...如果 NODE_ENV 变量设置为生产,我将发送我的脚本/css 的缩小版本。我认为这是目前最优雅的解决方案。
回答by Dickeylth
There are build tool plugins for you, may help you gracefully solve this problem:
有适合您的构建工具插件,可以帮助您优雅地解决这个问题:
For Gulp: https://www.npmjs.org/package/gulp-useref/
对于 Gulp:https: //www.npmjs.org/package/gulp-useref/
For Grunt: https://github.com/pajtai/grunt-useref
回答by Tomty
Another Node.js module which could be relevant is connect-cachify.
另一个可能相关的 Node.js 模块是connect-cachify。
It doesn't seem to do the actual minification for you, but it does let you serve the minified version in production, or all the original scripts in development, without changing the templates (thanks to cachify_js
and cachify_css
).
它似乎并没有为您做实际的缩小,但它确实让您在生产中提供缩小版本,或在开发中提供所有原始脚本,而无需更改模板(感谢cachify_js
和cachify_css
)。
Seems it's not as feature-rich as Piler, but probably a bit simpler, and should meet all the requirements mentioned in the question.
似乎它不像 Piler 那样功能丰富,但可能更简单一点,并且应该满足问题中提到的所有要求。