B4J Library [BANano] BANanoPostProcessor

Hello,

i like the BANano feature MinifyOnline very much. But -- to be honest -- I don't have a good feeling about sending my code to an online service.

That's why I wrote a small PostProcessor that, when compiled as a B4J lib, can compress JavaScript "offline" after BANano has done its job. For this I use Terser (https://github.com/terser-js/terser), which can be installed as NodeJs npm module. (I don't like NodeJS, but as far as I know there is no standalone tool available that produces better results.)

My current project will be reduced from about 182 kB to about 93 kB within 1.5 seconds with Terser's default settings. I think, that's not bad.

At the moment the PostProcessor can only compress the JS, but maybe I (or you?) will have ideas for futher features later.

Prerequisites:


How to use:

  • Download and unpack the attached ZIP

  • Load the BANanoPostProcessorProject.b4j and compile it to a Lib. B4J will place it automatically to the additional libraries folder.

  • Load your BANano-Project and insert the following code:

B4X:
Sub Process_Globals
    Private BANano As BANano
    Private BP As BANanoPostProcessor
    ' ...
End Sub

Sub AppStart(Form1 As Form, Args() As String)

  Dim appShortName As String = "[YourProjectName]"

  BANano.Initialize([YourEventName], appShortName, DateTime.Now)

  ' ...
  ' BANano-Stuff
  ' ...
 
  Dim BuildFolder As String = "C:\inetpub\wwwroot\BANano\" ' <- adjust to your needs!

  BANano.Build(BuildFolder)

  ' ####

#If Release ' It is recommended to use the Compress command only in release mode.

BP.Initialize
BP.ScriptFilename = BuildFolder & appShortName & "\" & BANano.SCRIPTS_FOLDER & "\" & BANano.JAVASCRIPT_NAME
BP.Compress

#End If

  ' ####

  ExitApplication

End Sub

Feel free to post questions, suggestions or bug reports.

Have fun & Greetings ... Peter
 

Attachments

  • BANanoPostProcessor.zip
    1.8 KB · Views: 439
Last edited:

Kiffi

Well-Known Member
Licensed User
@Mashiane : Merging third party JS and CSS files is usually something you do once, not every time BANano runs. Or did I get something wrong?

Greetings ... Peter
 

Mashiane

Expert
Licensed User
@Mashiane : Merging third party JS and CSS files is usually something you do once, not every time BANano runs. Or did I get something wrong?

Greetings ... Peter

I understand but for example you are developing, testing and debugging an app and add additional js and css files for more app functionalities and thus your app becomes a little more and more heavier. Once all the bugs are fixed then you consolidate. Just thought you could advise of any offline functionality that one could use.

Ta!
 

Kiffi

Well-Known Member
Licensed User
something like this?

Paste this code into the module BANanoPostProcessor (and recompile it as a library):
B4X:
Public Sub MergeFiles(FilesToMerge As List, TargetFile As String)
   
    Try
       
        If FilesToMerge.Size = 0 Then
            LogError("No files to merge!")
            Return
        End If
       
        Log("Merging files...")

        Dim FileContent As String

        For Each FileToMerge As String In FilesToMerge
            If File.Exists(File.GetFileParent(FileToMerge), File.GetName(FileToMerge)) Then
                FileContent = FileContent & File.ReadString(File.GetFileParent(FileToMerge), File.GetName(FileToMerge))
            Else
                LogError("File: " & FileToMerge & " doesn't exists")
            End If
        Next
   
        File.WriteString(File.GetFileParent(TargetFile), File.GetName(TargetFile), FileContent)

        Log("Merging files: Ready")
   
    Catch
       
        LogError(LastException)
       
    End Try

End Sub

and call it with:
B4X:
Dim FilesToMerge As List
FilesToMerge.Initialize
    
FilesToMerge.Add("E:\test1.js")
FilesToMerge.Add("E:\test2.js")
FilesToMerge.Add("E:\test3.js")
    
BP.MergeFiles(FilesToMerge, "E:\Target.js")

Greetings ... Peter
 

Mashiane

Expert
Licensed User
Compressing CSS Offline

I have been looking for an offline css minifier, so far it seems to be working well, managed to find clean-css here, https://github.com/jakubpawlowicz/clean-css-cli

This is inspired by the code in this post...

Start NodeJS and execute...

B4X:
npm install clean-css-cli -g

In the post processing code module add the following code

On Class Globals

B4X:
Private mCSSFilename As String

Inside the module, add the following code...

B4X:
Public Sub CleanCSS()
    startTime = DateTime.Now
    oldLength = File.Size(File.GetFileParent(mCSSFilename), File.GetName(mCSSFilename))
    Dim shlCompress As Shell
    shlCompress.Initialize("shlCleancss", "cmd.exe", Array("/c", "cleancss", File.GetName(mCSSFilename)))
    shlCompress.WorkingDirectory = File.GetFileParent(mCSSFilename)
    shlCompress.Run(10000)
    StartMessageLoop
End Sub

Public Sub getCSSFilename() As String
    Return mCSSFilename
End Sub

Public Sub setCSSFilename(Value As String)
    mCSSFilename = Value
End Sub

Private Sub shlCleancss_ProcessCompleted(Success As Boolean, ExitCode As Int, StdOut As String, StdErr As String)
    Try
        endTime = DateTime.Now
        If Success Then
            If StdOut.Length > 0 Then
                newLength = StdOut.Length
                Log("File Name: " & File.GetName(mCSSFilename))
                Log("Length (before): "  & oldLength & " Bytes")
                Log("Length (after): "   & newLength & " Bytes")
                Log("Bytes saved: " & (oldLength - newLength) & " Bytes")
                Log("Time: " & (endTime - startTime) & " milliseconds")
                File.WriteString(File.GetFileParent(mCSSFilename), File.GetName(mCSSFilename), StdOut)
            Else
                LogError(StdErr)
            End If
        Else
            LogError("Compress: Failed")
        End If
    Catch
        Log(LastException)
    End Try
    StopMessageLoop
End Sub

Usage

B4X:
BP.Initialize
BP.ScriptFilename = BuildFolder & appShortName & "\" & BANano.STYLES_FOLDER & "\mycssfile.css"
BP.CleanCSS

Disclaimer: I am using this at my own risk as there are some various options that one can set for the clean-css module.

My results so far:

B4X:
File Name: uoemock.css
Length (before): 539750 Bytes
Length (after): 480966 Bytes
Bytes saved: 58784 Bytes
Time: 1867 milliseconds

TA!
 

LJG

Member
Hello, I am new to B4J and I am interested in BANano in regard to PWAs. I am trying to learn from several examples and many of them require the BANanoPostProcessor library. I followed the instructions and created the BANanoPostProcessor library. But when I attempt to use it, several of the BANanoPostProcessor properties/options that are referenced as belonging to the BANanoPostProcessor library do not show up - for example:
PublishPath, ShortName, AssetsPath, ScriptsPath, etc. There were no errors when I installed terser or when I created the library from the BANanoPostProcessor.zip files as instructed. I would appreciate any help or suggestions, thank you.
 

Mashiane

Expert
Licensed User
Hello, I am new to B4J and I am interested in BANano in regard to PWAs. I am trying to learn from several examples and many of them require the BANanoPostProcessor library. I followed the instructions and created the BANanoPostProcessor library. But when I attempt to use it, several of the BANanoPostProcessor properties/options that are referenced as belonging to the BANanoPostProcessor library do not show up - for example:
PublishPath, ShortName, AssetsPath, ScriptsPath, etc. There were no errors when I installed terser or when I created the library from the BANanoPostProcessor.zip files as instructed. I would appreciate any help or suggestions, thank you.

EDIT: I think the examples you are referring to are related to the source codes I have written and I updated some parts of the BP to meet my needs based on the provided source code. To eliminate any confusion, can you please start a new thread and be specific about the examples you are having a problem with.

I am sure in all my code examples where the edited BP was used, the updated source and compiled libraries were provided.


All the best.
 
Last edited:

Kiffi

Well-Known Member
Licensed User
@Mashiane :

I am not pleased that you have also called your code extensions (based on my code) BANanoPostProcessor and published it without sources and any reference to me. This leads inevitably to misunderstandings (as you can see now for example from the request from LJG)

But not mentioning the original authors seems to be a general problem with your codes. For example, neither BANanoVuetify nor BANanoWebix contains a single reference to Alain Bailleul.
 

Mashiane

Expert
Licensed User
@Kiffi

Thanks for making the source code of the BP available so that we can all use as we see fit and adopt it to meet our needs. With that said, there has not been any re-publication of the BP here in the forum as my own. Everyone here knows that the BP is yours. For the code examples I wrote, I updated the original source code your provided to meet my needs for my projects. I am sure in all instances I have done so I have made available for all my code bases working examples and updated code bases.

Sadly its been long since I did any maintenance to "old" code here that might have been using it because there has been a lot of evolving with BANano, thus my request to @LJG to start a new thread so that we can provide him the help he needs.

I am also sure that in all instances where I have used your BP in my old projects, I have given the credit that is due.

Have a great evening.

PS: By the way, a month or so ago I did a blog here in the forum talking about BANano, this featured BANanoVuetify/BANanoVueMaterial and a part about your work on BANanoKendoUI (for desktop) and NW, check it out, https://www.b4x.com/blog/from-south-africa-to-central-america-with-love-a-banano-story/
 
Last edited:

LJG

Member
Thank you Mashiane and Kiffi for your hard work and contributions to this wonderful project. And my apologies for not starting a new thread. I will be sure to do that the next time I have a question or issue. And I look forward to learning more as I explore how to use B4J/BANano/libraries to create/modify BANano PWAs that score high in Lighthouse.
 

alwaysbusy

Expert
Licensed User
how to use B4J/BANano/libraries to create/modify BANano PWAs that score high in Lighthouse
Note that lighthouse scores will highly depend on how the maker of a BANanoLibrary has implemented his wrap. If it uses a lot of unused JavaScript and CSS, scores will drop down fast. I'm working on a PWA demo for the next release of BANano (couple of weeks because of other stuff I have to do for my day job) using a highly optimized version of the BANanoSkeleton lib for the UI which will hopefully give you the best scores possible. There can be big difference in performance/score depending on how a wrap was implemented.
 

LJG

Member
Note that lighthouse scores will highly depend on how the maker of a BANanoLibrary has implemented his wrap. If it uses a lot of unused JavaScript and CSS, scores will drop down fast. I'm working on a PWA demo for the next release of BANano (couple of weeks because of other stuff I have to do for my day job) using a highly optimized version of the BANanoSkeleton lib for the UI which will hopefully give you the best scores possible. There can be big difference in performance/score depending on how a wrap was implemented.
Thank you, alwaysbusy. Thank you for creating the foundational work for PWAs in B4J! As I learn more about BANano, I am simply amazed by your work ethic and commitment to this project. I learned a lot about streamlining PWAs by working in Ionic's Stencil (Stencil Website). But, as an old school VB6 programmer, I'd rather work in the B4J/BANano environment. For me, PWA's are the way to go in regard to cross-platform solutions. But, they must be fun to create, look good, and respond well. And I think that with B4J and your BANano ... it can all be done. I still have a lot to learn here, but I really like what I see so far. I'm looking forward to future releases of your work, thanks again.
 
Top