Search code examples
angulartypescriptwebpacksystemjs

How to detect the right body dimension with Webpack and SystemJS?


I'm doing an Angular2 library which has to be compatible with SystemJS and Webpack. For one component, I need to detect the height and width in pixels of the body tag as soon as to set dimensions in pixels for children tags. The behaviour between SystemJS and Webpack for the Angular LifeCycle make different results. I did this to explain it :

foo.component.ts

ngOnChanges() {
    console.log("ngOnChanges : " + document.body.clientHeight);
}

ngOnInit(){
    this.elHTML.setAttribute("direction", this.direction.toString());
    console.log("ngOnInit : " + document.body.clientHeight);
}

ngDoCheck() {
    console.log("ngDoCheck : " + document.body.clientHeight);
}

ngAfterContentInit() {
    console.log("ngAfterContentInit : " + document.body.clientHeight);
}

ngAfterContentChecked() {
    console.log("ngAfterContentChecked : " + document.body.clientHeight);
}

ngAfterViewInit() {
    console.log("ngAfterViewInit : " + document.body.clientHeight);
}

ngAfterViewChecked() {
    console.log("ngAfterViewChecked : " + document.body.clientHeight);
    this.widthHeightApply();
}

widthHeightApply(){
    var offsetWidth : number = document.body.clientWidth;
    var offsetHeight : number = document.body.clientHeight;
    ...
}

SystemJS result

ngOnChanges : 767
ngOnInit : 767
ngDoCheck : 767
ngAfterContentInit : 767
ngAfterContentChecked : 767

Webpack result

ngOnChanges : 40
ngOnInit : 40
ngDoCheck : 40
ngAfterContentInit : 206
ngAfterContentChecked : 206

Why there is a different result ? How can have the same result ?


Solution

  • I found the solution. About the body width, the difference between the real body width (1600px) and what the console displayed ("1583px") is due to the loading Angular page. Before loading the angular project, the index.html file has no CSS style that means there is a margin for the body and a scrollbar. That's why during the loading, the page is shaking. The solution is to insert normalize.css directly in the of index.html like this :

    Hard coding

    index.html

    <head>
     <meta charset="utf-8">
     <meta http-equiv="x-ua-compatible" content="ie=edge">
     <meta name="viewport" content="width=device-width, initial-scale=1">
    
     <title><%= htmlWebpackPlugin.options.title %></title>
    
     <meta name="description" content="<%= htmlWebpackPlugin.options.title %>">
    
     <% if (webpackConfig.htmlElements.headTags) { %>
       <!-- Configured Head Tags  -->
       <%= webpackConfig.htmlElements.headTags %>
     <% } %>
    
     <!-- base url -->
     <base href="<%= htmlWebpackPlugin.options.metadata.baseUrl %>">
    
     <!-- Normalize.css (the solution) -->
     <link rel="stylesheet" type="text/css" href="./styles/normalize.css" />
    </head>
    

    gulp injection from library

    In my case, I'm making a npm package. During the installation, the gulfile.js of my library inject this css code line in the index.html. I used gulp-insert-lines to do it like this :

    package.json

    {
     ...
     "scripts": {
       "postinstall": "gulp install --gulpfile gulpfile.js",
     ...
    

    }

    gulpfile.js

    var insertLines = require('gulp-insert-lines');
    ... 
    gulp.task('install', function() { 
         return gulp.src(indexPath + 'index.html', {base: './'})
                      .pipe(insertLines({
                      'before': /<\/head>$/,
                      'lineBefore': '<link rel="stylesheet" type="text/css" href="./styles/normalize.css" />'
                }))
                .pipe(gulp.dest('./'));
     });