AJAX Built and Deployment Environment especially javascript and css min, full versions - javascript

Currently I have one QA server to run on, svn update can be run there to test the code that everyone commits to subversion.
The issue I have seen with more and more javascript and css that the min or full version that get compiled, eg:
Build tool: Jake
JS compressor: UglifyJS
CSS optimizer: CSSO
either have to manually be updated/compiled just before promotion to production servers or we just have the min/full version on our svn but that would be not so great.
The way I see an approach would be:
* keep the full/split css java script files outside of the path where web served content sits, subversion or trac builds the min/full version on submit/trigger.
Has anyone further automated this process?
How do you separate your full source/full version/min version as not to mess up final deployment? When do you compile the min version?
Only at the last step before going to production?
Where do you leave the original source, it cannot live right next to the web served other files, in my example php files?

Just been dealing with something similar myself. If I understand your question correctly you're looking to have unminified files in a local or dev environment but have them minified upon deployment. There are, of course, many different ways that you can go about this, and we're currently working on a better solution but I'll give you an example of a project I just finished up...
Uses symfony 1.4, YUI Compressor, and git.
I have a symfony task (php cli script) set up to run YUI Compressor on a given list of css and js files, which get dumped into min.css and min.js in the appropriate directories. The script simply dumps all of the contents of the listed files into one big file and minifies them. Then symfony is set to only use min.js. Of course, debugging minified files can be a pain, so another option is to skip minifying on your local or dev boxes and just keep them as a combined file. Personally I have it minifying anyway because Chrome's "Pretty print" option works well enough for me most of the time, although it's not 'ideal'.
I've created a local post-commit and server side post-merge script for git that simply runs the symfony task so the files are automatically updated whenever you commit locally or do a git pull on the server, so any changes made inside the js/css files are updated when committing. The only pain point of this is having to manually run the minify script whenever you've updated locally but haven't yet committed.
An alternative to keep unminified code on local/dev would require some more coding so that it is environment specific, which is certainly doable but I've just been lazy with it thus far as this works well enough for now :)

I have taken the following convention-based approach and it works well for me for traditional web-development as well as for mobile apps and offline HTML5 mobile apps.
Conventions
All non-minified/full-version js/css scripts are named with .debug.js or .debug.css extensions.
Example: global.debug.js and global.debug.css
All references to js/css in html reference non-debug versions: global.js or global.css
Process
I use a custom MSBuild task to minify js (using AjaxMin, but you could use YUI Compressor or others) to the following naming convention *.release.js or *.release.css
(Example: global.release.js).
After minification into the *.release.js files. I have one more MSBuild task that calls a simple batch file (JS.bat) that accepts the current Configuration (Debug or Release) and copies either the debug (full-source version) or the release (minified) version to the normal destination.
Here's the sample MSBuild tasks I add to my project file to accomplish the minification and call to my batch file:
<Import Project="$(MSBuildExtensionsPath)\Microsoft\MicrosoftAjax\ajaxmin.tasks" />
<Target Name="AfterBuild">
<ItemGroup>
<DebugJS Include="**\*.debug.js" />
</ItemGroup>
<AjaxMin SourceFiles="#(DebugJS)" SourceExtensionPattern="\.debug.js$" TargetExtension=".release.js" />
<Exec Command="JS.bat $(Configuration)" />
</Target>
For example, assuming:
I'm in Debug mode
and I have a global.debug.js file (full-source version that I work in)
When I build my project, global.debug.js get's minified into global.release.js
Since I'm in the Debug mode configuration, global.debug.js will get copied to global.js (which is what my html references) and, therefore, I'll have the full-source version when debugging
If I switch to Release mode configuration, then global.release.js (the minified version) gets copied to global.js and this is what I would want for release/deployment to production.
Here's the simple batch script (JS.bat) that I use to handle the copy of the Debug or Release script based on the passed argument:
#Echo off
REM ----------------------------------------------------------------------------------------
REM <summary>
REM Script used to copy the Debug (or Release) javascript files to the runtime location
REM </summary>
REM <history>
REM <change date="9/22/2010" author="Adam Anderly">Created</change>
REM </history>
REM ----------------------------------------------------------------------------------------
REM Grab the first argument as variable Config (Debug/Release)
SET Config=%~1
REM The loop below is used to get the Length of the Config variable
REM The Length variable is then used in the substring function on Line 22
for /f "tokens=1 delims=:" %%a in (
'^(echo."%Config%"^& echo.!##^)^|findstr /O /C:"!##" '
) do set /a Length=%%a-5 + 4
FOR /R %%i IN (*.%Config%.js) DO CALL :REN "%%i"
GOTO :END
:REN
SET File=%~f1
REM Set File2 variable to the runtime filename (minus .debug or .release)
CALL SET File2=%%File:~0,-%Length%%%.js
REM First make sure the destination file is not read-only
IF EXIST "%File2%" ATTRIB /S -R "%File2%"
REM Finally, we copy the current debug|release file to the runtime file
COPY /Y "%File%" "%File2%"
:END
The batch script above works recursively so you can have nested folders of js or css and it still works.
While I'm using MSBuild, you could certainly incorporate this batch file into your process using a different build tool (previously I did the same using NAnt).
Hope that helps!
Adam

Related

CSS not added to /dist folder using Webpack 4 and MiniCssExtractPlugin

Issue
Would any Webpack config experts out there be able to tell me why I can't extract my css into the dist folder when running npm run build?
Repo is here: https://github.com/damodog/webpack4-boilerplate
Further info
To summarise, I've been working through the Webpack Guide docs and everything was going well. js and css was getting injected into my index.html file via <link> and <script> tags respectively. I've installed various loaders, plugins etc and split my configs out into common (shared), dev and prod files (as per the docs) and life was good.
I happened to make some tweaks which included looking at code splitting dynamic imports, adding aliases for paths, moving js into js folder etc and noticed when I ran a build npm run build all of a sudden my css wasn't getting added to the dist folder. I reverted my trial changes for the dynamic import stuff and tried reverting the other changes but am still getting the same issue. Annoyingly I hadn't added git at this point so didn't have a clear picture of the 'tweaks' I'd made to locate what I'd changed.
What happens
When I run my watch task npm start the styles.scss file (imported into the main index.js file) get's compiled into css and the resulting app.css file gets injected into the index.html page when viewed in my local host. All gravy.
<link href="css/app.css" rel="stylesheet">
When I run npm run build the css file should get copied over dist folder, a hash id should get added and the css should be minified. This was working (like I said above) and I could see the css file in the build steps (see first Asset below. Btw disregard the difference in js bundled files here compared to the next screenshot. This was when I was playing with code splitting).
Now when I run this the css isn't bundled up (see below).
I think it could be something to do with mini-css-extract-plugin but I've configured this as per the docs using the advanced configuration example (I've split their example out which is in one config file as I have separate config files for dev and prod).
I literally cannot see why this is happening.
Help me SO readers. You're my only help...
I cloned your repo and experimented with it. In your package.json, you've set: sideEffects: false. This causes the imported stylesheets to be lost in the process of tree shaking. This is described in the docs:
A "side effect" is defined as code that performs a special behavior
when imported, other than exposing one or more exports. An example of
this are polyfills, which affect the global scope and usually do not
provide an export.
and
Note that any imported file is subject to tree shaking. This means if
you use something like css-loader in your project and import a CSS
file, it needs to be added to the side effect list so it will not be
unintentionally dropped in production mode
So change your side effects in package.json to "sideEffects: ["./src/scss/styles.scss"] and it will be output to the destination folder when in production mode.

How can we version our JavaScript files

The context : we are working on Windows OS (VS 2017, VS Code) with many JavaScript files, for ex: in the 'controls' folder we will have control1.js, control2.js etc (different people working on different controls).
|- controls
|- control1.js
|- control2.js
On the 'apps' folder we will have :
|-apps
|- app1
|- view.js
|- controller.js
|- model.js
|- app2
|- view.js
|- controller.js
|- model.js
Now, the idea is that the testing team will/might find errors that needs to be fixed. We will fix the code and re-deploy the fixed file (for ex. control1.js) to the specific testing team. If another team (working on a different environment) reports another error in the same file (control1.js) there is no way for us to know if the current environment has the fix mentioned above or not (only code-compare will tell us).
There is no file version that will help us know where (in what version) the issue happened and in what version it was fixed.
What do we want - (maybe this problem was already solved but I didn't find anything) - we want that # check-in-time the version of the JavaScript file to be increased (probably the release number as in C#). We are using as version-control TFS (on premises) and VSTS/Git (online at visualstudio.com).
How ? - each JavaScript file will have some sort of header (a large area at the top of the file with some commented text) that will contain some information about the company etc ... and also the version of the file ex.: 1.0.2.23.
In this way we will know in what version a fix was done (the bug tracking system requires us to mention in what version the bug was found and in what version it was fixed.
How can we simulate this in VS 2017 (2015) and also in VS Code ?
Can we have a single file (the same as AssemblyInfo.cs in C#) common to all JavaScript files and than that file to be ... merged with each JavaScript file?In this way, if we need to change something globally we will not need to ... find/replace all over the place ?
Thank you in advance.
For the situation that a file (such as control1.js) need to be modfied by multiple people:
If the file need to be double tested by testing team after you fixed, you can modify the file on another branch and then merged into current working branch by testing team.
If testing team won’t test the fixed file, you can modify the file directly on current branch, and push the branch to TFS/VSTS. After that, if other team members also need to modify the same team, they can pull the changes you made and fix the file based on the newest version.
For the version of file:
Actually it’s a new version when you commit changes every time, git will calculate a new SHA-1 checksum (commit id) like a11bef06a3f659402fe7563abf99ad00de2209e6, you can view in VS -> Team Explorer -> Branches -> right click a branch -> View History.
If you want to a version more readable, you can add a tag for a commit, such as in View History -> right click a commit -> Create Tag -> then enter a tag name such as 1.0.2.23.
And you don’t need a single file to record the file version since git can manage the versions for every changes you made.
To get the version that test team deployed, you can use these steps: open the release -> Artifacts -> find the build definition and build version -> find the build version in build Tab -> in the summary page you can find git version in Source version.
We use versions formed as <major>.<minor>.<changeset>-<buildid>-<branch> to keep track of versions deployed. On each deploy custom IIS response header field "X-Release" is updated with version number so that QA/PM always can check what code version they are working with in the developers tools:
However, we are using Octopus Deploy so cannot tell how to do this in TFS release.

Configure webpack to allow browser debugging

I am new to webpack and I am converting an existing web application to use it.
I am using webpack to bundle and minify my JS which is great when deployed, however this makes it very challenging to debug while in developement.
Typically I use chrome's built in debugger to debug JS issues. (Or Firebug on firefox). However with webpack everything is stuffed in one file and it becomes challenging to debug using that mechanism.
Is there a way to quickly turn on and off bundeling? or turn on and off minifying?
I have looked to see if there is some script loader configuration or other setting but it does not appear ovious.
I have not yet had the time to convert everything to act like a module and use requires. So I simply use require("script!./file.js") pattern for my loading.
You can use source maps to preserve the mapping between your source code and the bundled/minified one.
Webpack provides the devtool option to enhance debugging in the developer tool just creating a source map of the bundled file for you. This option can be used from the command line or used in your webpack.config.js configuration file.
Below you can find a contrived example using the command line to generate the bundled file (bundle.js) along with the generated source map file (bundle.js.map).
$ webpack --devtool source-map ./entry.js bundle.js
Hash: b13b8d9e3292806f8563
Version: webpack 1.12.2
Time: 90ms
Asset Size Chunks Chunk Names
bundle.js 1.74 kB 0 [emitted] main
bundle.js.map 1.89 kB 0 [emitted] main
[0] ./entry.js 85 bytes {0} [built]
[1] ./hello.js 59 bytes {0} [built]
index.html
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script src="bundle.js"></script>
</body>
</html>
entry.js
var hello = require('./hello.js');
document.body.innerHTML += 'It works ' + hello();
hello.js
module.exports = function () {
return 'Hello world!';
};
If you open index.html in your browser (I use Chrome but I think it is also supported in other browsers), you will see in the tab Sources that you have the bundled file under the file:// scheme and the source files under the special webpack:// scheme.
And yes, you can start debugging as if you had the original source code! Try to put a breakpoint in one line and refresh the page.
I think its better to setup your project using production and development mode
https://webpack.js.org/guides/production/
Its also include how to map your code to debug
devtool: 'inline-source-map'
Source maps are very useful as already pointed out.
But sometimes selecting which source map to use could be a pain.
This comment on one of the Webpack source map issue might be helpful for selecting which source map to use based on requirements.
Chrome also has a format option in the debugger. It doesn't have all the information a normal source file would but it's a great start, also you can set breakpoints. The button you click is on the bottom left of the first screen shot, looks like {}.
Before formatting:
After formatting.
Have a look Here
its a beautifier that deminifies javascript. at the bottom, it has a list of various plugins and extensions for browsers, check them out.
you might be interested in FireFox Deminifier , its supposed to deminify and style your javascript when its retrieved from the server.
(source: mozilla.net)

In Visual Studio 2013, how do I minify Javascript and CSS in the post-build step

In Visual Studio 2013, how do I minify Javascript and CSS in the post-build step? I'd like to have every single css and js file compress into a .min.js, or .min.css in the same folder.
I don't want to check in the minified files, but rather just have them generated post-build.
All solutions I found required using different filenames for the minimized versions, and a lot of extra work to switch between using the normal/minified versions.
Instead, I wanted the compressed JavaScript files to have the original names so I didn't have to change the references in my HTML markup. I could use the normal Javascript files in my development environment, then minimized versions would be automatically deployed when publishing.
I found a simple solution that does just that.
First, install Microsoft Ajax Minifier.
Then, in your Visual Studio project file, just before the closing </Project> tag add the following :
<Import Project="$(MSBuildExtensionsPath)\Microsoft\Microsoft Ajax Minifier\ajaxmin.tasks" />
<Target Name="AfterBuild" Condition="'$(ConfigurationName)'=='Release'">
<ItemGroup>
<JS Include="**\*.js" Exclude="**\*.min.js;obj\**\*.*" />
<CSS Include="**\*.css" Exclude="**\*.min.css;obj\**\*.*" />
</ItemGroup>
<AjaxMin
JsSourceFiles="#(JS)" JsSourceExtensionPattern="\.js$" JsTargetExtension=".jsMIN"
CssSourceFiles="#(CSS)" CssSourceExtensionPattern="\.css$" CssTargetExtension=".cssMIN" />
</Target>
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
</PropertyGroup>
<Target Name="CustomCollectFiles">
<ItemGroup>
<MinJS Include="**\*.jsMIN" />
<FilesForPackagingFromProject Include="%(MinJS.Identity)">
<DestinationRelativePath>%(RecursiveDir)%(Filename).js</DestinationRelativePath>
</FilesForPackagingFromProject>
<MinCSS Include="**\*.cssMIN" />
<FilesForPackagingFromProject Include="%(MinCSS.Identity)">
<DestinationRelativePath>%(RecursiveDir)%(Filename).css</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
What does the above code do? When you publish in Visual Studio, this code will find every .js and .css file in your source, and create a minified copy using the extension .jsMIN and .cssMIN. It will ignore files that are already minified. Then it will copy these minified files to the deployment folder, using the original file names.
Voilà! You just published minified JS/CSS files, while your original files stay intact on your development environment.
Optional:
Want Ajax Minifier to be packaged with your project? From the Ajax Minifier install folder, you can move AjaxMin.dll and AjaxMinTask.dll directly into your source directory. I put them in my App_Data folder. Once they're somewhere in your source, in Visual Studio right-click them, select Include in Project, and also change their Build Action property to None.
Then in the code I included above, change
<Import Project="$(MSBuildExtensionsPath)\Microsoft\Microsoft Ajax Minifier\ajaxmin.tasks" />
to
<UsingTask TaskName="AjaxMin" AssemblyFile="$(MSBuildProjectDirectory)\App_Data\AjaxMinTask.dll" />
Done.
A troubleshooting tip:
My main code above executes AfterBuild and only when the configuration is Release. That's so it will only run during a publish. If your configuration is named something else, or you want it to run in other circumstances, modify the code as needed.
With Microsoft Ajax Minifier you could create powershell script to create minified versions of all files in given folder and add it to Post-build events.
Example for js files(it will be similar for css):
Get-ChildItem *.js -Exclude *.min.js |
Foreach-Object{
$file = [io.fileinfo]$_.Name
ajaxmin $file.Name -out "$($file.Name).min$($file.Extension)"
}
Check also a page with full list of command line switches e.g.: -map creates source map file.

version control: how to control css and js compressed/minified versions between environments

I am using git (via GitHub) for version control on my projects. I'm still new to this but I'd like to know best practice for how to keep my css and js files synchronized between environments.
Example: Let's say I write a js script on dev. I'm happy with my work and I push to testing. Well on testing I would want a minified/compressed version. How would I accomplish that without a lot of overhead tasking? What do you guys do? I'm assuming it's part of some sort of deploy script that would compress the code and push it to whatever environment I specify.
This brings up another question: What about my header (and/or footer) file(s) in my project? If my dev has:
<link rel="stylesheet" href="<?php echo base_url(); ?>css/main.css">
and my testing has:
<link rel="stylesheet" href="<?php echo base_url(); ?>css/main.min.css">
That's all fine, but what if I need to make changes to my header? How would I separate all these things from each other? If I make changes to my header and push to testing or production I would lose the .min from that include line.
Currently what I do to deploy updates is just a simple git pull origin [branch] from the command line inside the environment I want to update.
Again, I'm looking for best practice, whatever learning it requires. Thanks!
You might want to check out preprocessor tools, such as LESS or Sass. These tools allow you to write CSS (I believe they may be able to handle JS, too, for purposes of minifying), and set up scripts that handle how they compile the code, based on the environment.
What you'd do, then, is write your code in "source" files, and set up the preprocesser to compile the code according to settings laid out in a settings file (for Sass, this is easily done with the Compass framework), based on the environment you're in. You'd then keep only the source files in the repository (set Git to ignore the compiled versions), and set up post-receive hooks to compile the source files on the server. Your HTML can then be written to access the compiled files (which should have the same name across environments), so you don't have to write logic that determines on the fly, every time, what environment the code is running in.
Don't put minified version of CSS, JS into version control. That's duplicate.
Git can be used on delopy but its purpose is not deploy.
For the including CSS tags, that's easy. A quick roundup is use your framework's env vairable. As I know CodeIgniter has this function. If env == test, include minified version, if not, include raw versions.
Besides you need a build script or framework plugin to generate minified versions automatically.
Typically a minified file is generated by your CMS on page load. So from a code standpoint you don't need to track the minified version as all the code is tracked in your actual js and css files. So minified copies can just be ignored using the .gitignore file.
My .gitignore file typically looks like:
css-min #directory to store generated minified css files
js-min #directory to store generated minified js files
tmp #directory to store temporary files
files/images/cache #directory for storing generated images such as thumbnails
settings.php #File that stores system variables.
The settings file is used to set global variables such as your platform like "dev", "staging", "production". Then in your other files you can check the platform as to which css/js files to use. Since that file is ignored by your repository you can make the settings specific to each platform.
if ($GLOBAL['platform'] = PLATFORM_DEV) {
$path = 'css/main.css';
}
elseif ($GLOBAL['platform'] = PLATFORM_STAGE) {
$path = 'css-min/main.min.css';
}
<link rel="stylesheet" href="<?php print base_url(); print $path; ?>">

Categories

Resources