MAUI app doesn't pick up compiled CSS from post build action - msbuild

I'm currently playing around with a MAUI Blazor app and set up Tailwind CSS instead of the default Bootstrap. This is done through Node.js for which I've set up an NPM script to build the CSS:
"scripts": {
"buildcss": "tailwindcss -o wwwroot/css/custom-tailwind.min.css --minify"
}
In the index.html I load this CSS file: <link rel="stylesheet" href="css/custom-tailwind.min.css" />.
Now, since Tailwind only includes the styles that my app actually uses (to minimize the file size), I want to rebuild this CSS file everytime I build my app. This is currectly done with a post build action:
<Target Name="BuildCSS" AfterTargets="PostBuildEvent">
<Exec Command="npm run buildcss" />
</Target>
The file is generated as expected, but when running the app, it doesn't seem to recognize the file and therefore no styling is loaded. Simply restarting the application after is enough for it to work, which means if the file already exists and is simply overwritten it works, but it annoys me.
Am I using the wrong build action or should this be done in a different way?
As a bonus question, is there a build action that will also be executed during Hot Reload?
I'm currently just testing it for a Windows app (net6.0-windows10.0.19041.0)

Related

Creating a single Vue component inside a larger project

I have a PHP project that uses Kirby CMS. I also use Gulp for building my assets. Now, I need to add a calculator on the homepage that is complex enough to justify the usage of Vue. How would I incorporate Vue in my project without introducing a ton of new tooling? All I want is a simple Single File Component basically. I have:
<div id="calculator"></div>
and I want the component to be rendered there. Nothing more.
After some consideration, I came up with the following options but found issues with each of them:
Use the Vue CLI for instant prototyping. That's the closest solution for my use case, but I can't easily develop the component. If I use vue serve, I get to see the component isolated in a new page. The issue lies in the fact the component isn't a part of my project's page. It's not affected by its stylesheets, layout, and other scripts. I can't know if it'll work properly once I build it and view it in my project. Running vue build on each change would be pretty painful and time consuming. Sadly, vue watch isn't a thing, which leads me to:
Creating a project and using Vue CLI Service. If I create a project, I'd be able to run vue-cli-service build --watch and have my component automatically refresh on each change of its source file. While developing the component, I simply make a change, wait for it to compile, and refresh my project in the browser to see the modified component in action. While that would work, it introduces a bunch of node_modules inside my project, along with a package.json. I feel that's too much for just a single component. It would pollute the project more than I'd like:
assets/
js/
build/
calculator/
dist/
node_modules/ # modules here
public/ # I don't need that
package.json # package here
package-lock.json
App.vue
scripts/
main.js
content/
site/
node_modules/ # modules here as well
panel/
package.json # package here as well
package-lock.json
index.php
I would basically have a project within a project.
Use vueify to compile the component with Browserify and Gulp (which I already use). While this appears OK, vueify is deprecated and not supported. Besides, I'd have to add a bunch of stuff to my gulpfile.js in order to use Babel + ESLint for the component.
How do I set up Vue in such a way that I'm able to develop a very simple component as a part of a larger project with as little friction as possible?
If anyone has dealt with a similar problem, how did they solve it?
I ended up using the second approach I mentioned in my question with one small twist - I initialized the Vue project in my main project. I merged them.
I opened the parent folder of my project in a terminal.
I ran vue create my-project where my-project was the actual folder name of my project. The CLI asked if it should overwrite the project or merge it. I chose merge.
After the project was created, my old package.json was overwritten and only had the Vue dependencies listed in it.
I reverted my old package.json and installed these packages: #vue/cli-plugin-babel, #vue/cli-service, vue-template-compiler, and vue.
I added the following npm script in my package.json:
"scripts": {
"calculator": "vue-cli-service build assets/js/calculator/main.js --watch --dest assets/js/calculator/build"
}
Result
My project's folder structure remained the same, except for a few new packages in node_modules. I put my component files in assets/js/calculator/. There, I have main.js which is the main component script, and build which is a folder containing the processed component.
I have:
<div id="calculator"></div>
in my page, and:
<script src="/assets/js/calculator/build/app.js"></script>
in the footer. When I open the page, the component is rendered correctly.
To modify the component, I simply run npm run calculator in a terminal, which spins up the CLI service. It monitors the main.js file and builds the component on each change. Once the build is complete (which happens in under a second), I refresh the page and the updated component is there.
Conclusion
I believe that's the smoothest way to handle this use case. It didn't bloat the project, all dependencies were listed, and the development experience is great. The part where my package.json got overwritten was a bit concerning, but other than that - it worked perfectly. If there's a better way to do this, please leave an answer!
This is probably not the answer you're looking for but if I were you I'd look into inline templates and x-templates as they seem well suited to your use case.
Also have a look at this blog post. It offers a nice write up about the different template authoring methods in Vue and their pros/cons.

How to bundle different js and css files per controller action/view?

I have site-wide js file (site.js) that goes out with every request.
I have 2 actions on the controller: Action1 and Action2. Each of these actions has a view. Each view references a view-specific js (action1.js and action2.js).
I would like to bundle site.js with action1.js when Action1 method is executing. And when Action2 method, I want to bundle site.js with action2.js.
The bundling should be done at build time.
Is this possible with .Net Core 1.x?
It's possible, but there's a lot of menial work involved, because you'll need to manually describe each view's bundle.
Everything you need to know can be found in the official documentation, but here's the gist of it:
Action1.cshtml
I assume that for debugging purposes, you want to include both files on your dev box, while you only want the bundle in production. In your view, you add the following tags:
<environment names="Development">
<script src="site.js"></script>
<script src="action1.js"></script>
</environment>
<environment names="Staging,Production">
<script src="view1.js" asp-append-version="true"></script>
</environment>
When in development, your two files will be included as is, while in production, the bundled file view1.js will be included.
asp-append-version is part of the cache busting mechanism: it will append the file's version to each request to that file (details here).
Create your bundled view1.js
There's a number of various possibilities to create the bundle, but they all revolve around the bundleconfig.json file. The simplest solution uses he BuildBundlerMinifier NuGet package, and simply requires you to add it to your project.
bundleconfig.json would look like this:
[
{
"outputFileName": "wwwroot/js/view1.js",
"inputFiles": [
"wwwroot/js/site.js",
"wwwroot/js/action1.js"
]
},
]
Repeat for each view
This is where things get boring, because you'll need to repeat this for each view.

why does sencha app build production replace my css file?

I've had to go back to an old version of compass: 0.12.7
Otherwise it fails on missing files. Before installing I removed the existing compass installation.
It correctly compiles my css file when I make a change to the scss file.
But when I ask sencha to make a production build with "sencha app build production" the css file in my project gets replaced with a different one.
The file probably gets overwritten at the following line during the build process:
[INF] executing compass using system installed ruby runtime
overwrite ../css/app.css
So it claims to use my installed version of compass.
What am I doing wrong here?
You have the same problem i have met.
Sencha touch 2.4.0 SASS compile error
You should not write your custom css in app.css.
IMHO, there are two ways to add custom css.
1. app.json
2. #import your custom scss file in app.scss in resource/sass/app.scss and then use sencha ant sass to compile css file.

Bootstrap JavaScript works on localhost but not on webhost

I am using Twitter Bootstrap Installed Using Buget to an ASP.NET MVC Application. I am however surprised to find that all my bootstrap JavaScript which used to work on localhost and in fact still do have all stopped working when uploaded to my web hosting provider.
I am completely bumped on this and I cant seem to figure out what is wrong.
Some of your scripts, which depend on jQuery, are being included before jQuery had been loaded.
bootstrap-dropdown.js is included before jQuery
your custom javascript on line 75 is included before jQuery
I'd suggest moving
<script src="/Scripts/bootstrap.js" type="text/javascript"></script>
<script type="text/javascript" src="http://twitter.github.com/bootstrap/assets/js/bootstrap-dropdown.js"></script>
and your custom javascript from line 75, to the bottom of your page, after the jQuery bundle is included. Or alternatively move your jQuery bundle into your <head>. It's your preference as to which - see this question: Should Jquery code go in header or footer? regarding that particular issue...
You say it's working on your local box and not on the remote server - if that's really the case then my best guess is that this is to do with the fact that bundling/minification works differently depending on whether you are in debug or release mode.
UPDATE
Basically, in a debug build, no bundling/minification is performed on your scripts and css. Each <link> and <script> that you reference in your bundles will be included as a separate file, with no transformations applied to them. In release builds, files in a bundle are concatenated together into one file, and transformations such as minification are applied to them. As per your comment, in order to get the debug behaviour in both your local and published sites, I see 3 options:
1. In your release build, set the compilation debug flag to true in your web.config.
i.e.
<system.web>
<compilation debug="true" />
<!-- Lines removed for clarity. -->
</system.web>
I wouldn't particularly recommend this, as your release build shouldn't generally be flagged as being debug. But this is a useful setting to quickly toggle on your release build to check if your javascript/css works correctly when it is off.
2. In code, turn off bundling optimizations in your bundle table.
public static void RegisterBundles(BundleCollection bundles)
{
// other code...
BundleTable.EnableOptimizations = false;
}
3. Don't do it.
The difference in behaviour is by design, and makes sense - on your local box doing development, you can see all the individual script/css files and in unminified form, which makes debugging far easier. When published, the files are squashed down into one single, compressed file, which will reduce load time for your site.
I'd personally recommend option 3, and just make sure your styles/scripts are being included in the correct order.
In your page you have
<link href="/Content/bootstrapcss" rel="stylesheet"/>
... there's a blip with the file type, maybe this should be
<link href="/Content/bootstrap.css" rel="stylesheet"/> ?
And there's a path problem with your Modernizr file, check that the path is correct and the file exists:
http://bipscore.com/Scripts/modernizr-1.7.min.js
There may be other issues, but wouldn't hurt to get these two corrected first.
Good luck!

Make meteor refresh stylesheet only

I've noticed that when working on a meteor application it will auto refresh the entire page when any stylesheets have changed. Is there a way to make it only refresh the stylesheet assets similar to how LiveReload works?
Also note that I'm using stylus for my stylesheets. Is that what's causing the full reload?
No, out-of-the-box Meteor will reload the entire app when it detects a file change of any type (whether html, css, or js). It doesn't matter if you're using stylus or not.
I imagine future iterations may take a page of out LiveReload for images and css files (so changing them does not cause a refresh), but for the time being the whole site will reload. In fact, this would probably be a fantastic pull request.
The current workaround I found is to use the "regular way" of adding css files:
Put your file myCss.css into the public folder "/public/myCss.css" so that it is not compiled by meteor
Add the following line to your html file:
<link rel="stylesheet" type="text/css" href="/myCss.css" />
Use a live editor such as Espresso or CSSEdit to change the myCss.css file.
Note that once you save the file, meteor will reload anyway. But in the following case:
- You are running meteor in production mode
- Your .css file is not in any folder contained into the meteor project (like you serve the .css file from somewhere else my yourself)
- Your file or folder is starting with a dot "." or ending with tilde "~", in this case, meteor will not reload those files if they did changed. Note that I never have been able to make this work with the ending tilde, moreover working with invisible files (starting with ".") is not very convenient. See here for ref.