SharePoint / sp-dev-docs

SharePoint & Viva Connections Developer Documentation
https://docs.microsoft.com/en-us/sharepoint/dev/
Creative Commons Attribution 4.0 International
1.24k stars 1k forks source link

How to turn off Mangle? (keep_fnames: true) #407

Closed BenGWeeks closed 7 years ago

BenGWeeks commented 7 years ago

Category

How to I switch off mangle? I know with the SPFx project we don't have a webpack config, and it's in the gulpfile.json, but how would I go about putting in:

new webpack.optimize.UglifyJsPlugin({
        beautify: false, //prod
        mangle: { screw_ie8 : true, keep_fnames: true }, //prod 
        compress: { screw_ie8: true }, //prod
        comments: false //prod
      }),

Related issue is here:

https://github.com/SharePoint/sp-dev-docs/issues/406

nickpape commented 7 years ago

We haven't provided a simple way to adjust the configuration options of the UglifyJS plugin, however, you can achieve the objective by replacing the Microsoft-provided plugin with your own. Here is an example:

build.configureWebpack.setConfig({
  additionalConfiguration: (config) => {
    var webpack = require('webpack');

    // Remove the Microsoft-provided Uglify plugin
    config.plugins.forEach((plugin) => {
      if (plugin instanceof webpack.optimize.UglifyJsPlugin) {
        var index = config.plugins.indexOf(plugin);
        config.plugins.splice(index, 1);
      }
    });

    // If you only want this to happen during a prod build, add the
    // following if statement:
    // if (build.getConfig().production) { ... }

    // Add our custom config plugin
    config.plugins.push(new webpack.optimize.UglifyJsPlugin({
      beautify: false,
      mangle: { screw_ie8 : true, keep_fnames: true },
      compress: {
        screw_ie8: true /*,
        warnings: false */  // if you don't want to see warnings from uglify
      },
      comments: false
    }));

    return config;
  }
});

Please note that we use the following settings in the Uglify plugin:

{
  compress: {
    dead_code: true,
    warnings: false
  },
  mangle: true
}

If you think it would be helpful, we can also provide an easy way to set the configuration for the Uglify plugin using a JSON config file, however, that would not be in the upcoming GA release.

BenGWeeks commented 7 years ago

I think in an ideal world we would be able to import a standard webpack type configuration file (perhaps webpack.dev.json and webpack.production.json). Webpack is not completing at the moment, and I have:

'use strict';

const gulp = require('gulp');
const build = require('@microsoft/sp-build-web');
var spsave = require('gulp-spsave');
var auth = require('./_private/settings');

// Ref: https://github.com/webpack/docs/wiki/configuration#outputpublicpath

build.configureWebpack.setConfig({
  additionalConfiguration: (config) => {
    var webpack = require('webpack');

    // Angular 2 fix, see: https://github.com/angular/angular/issues/10618
    // Remove the Microsoft-provided Uglify plugin
    // If you only want this to happen during a prod build, add the
    // following if statement:
    // if (build.getConfig().production) { ... }
    config.plugins.forEach((plugin) => {
      if (plugin instanceof webpack.optimize.UglifyJsPlugin) {
        var index = config.plugins.indexOf(plugin);
        config.plugins.splice(index, 1);
      }
    });
    // Add our custom config plugin
    config.plugins.push(new webpack.optimize.UglifyJsPlugin({
      beautify: false,
      mangle: { screw_ie8 : true, keep_fnames: true },
      compress: {
        screw_ie8: true /*,
        warnings: false */  // if you don't want to see warnings from uglify
      },
      comments: false
    }));

    //config.devtool = 'source-map';

    // Workaround for ng2, see: https://github.com/angular/material2/issues/1335#issuecomment-277157354
    //config.htmlLoader = {
    //    minimize: false // workaround for ng2
    //}

    config.module.loaders.push([
      { test: /\.(woff|woff2)$/, loader: "url-loader?limit=10000&mimetype=application/font-woff" },
      { test: /\.ttf$/, loader: "file-loader" },
      { test: /\.html$/, loader: "html-loader?-minimize" }, // workaround for ng2
      // { test: /\.html$/, loader: "html?-minimize" }, // workaround for ng2
      // { test: /\.html$/, loader: "html-loader", query: { minimize: false } }, // workaround for ng2
      { test: /\.eot$/, loader: "file-loader" },
      { test: /\.svg$/, loader: "file-loader" },
      { test: /\.scss$/, loaders: ["style-loader", "css-loader?sourceMap", "sass-loader?sourceMap"]}      
    ]);

    return config;
  }
});

build.initialize(gulp);

gulp.task('changeBase', function(){
 // gulp.src(['./dist/index.aspx'])
 //   .pipe(replace('<base href="/">', '<base href="/sites/Development/R2Dev/SitePages/ng2/index.aspx">'))
 //   .pipe(gulp.dest('./dist'));
});

gulp.task("spsave",['changeBase'], function () {
    return gulp.src(["./dist/**/*.*"])
        .pipe(spsave({
            siteUrl: auth.siteCollectionUrl,
            folder: "SiteAssets/[somefolder]",
            flatten: false
        }, auth));
});

Related issue:

angular/material2#1335 (comment)

BenGWeeks commented 7 years ago

I would also add, that personally I would prefer if we switch off as much of this bundling stuff as possible, in the sense that for dev, we already have 1 level of abstraction with code being transposed from .ts to .js, but when the code is also bundled up into inline css and a single js file makes it again more difficult to debug. That's the kind of thing we can switch on if we want to be clever - and probably at SP1 ;-)

BenGWeeks commented 7 years ago

Ah, OK, does eventually fail with:

Declarations in unreachable code! [requirements-form.bundle.js:190,12635]
Dropping unreachable code [requirements-form.bundle.js:190,21900]
Declarations in unreachable code! [requirements-form.bundle.js:190,21900]

Error - [webpack] 'dist':
./lib/webparts/requirementsForm/app/app.component.html
Module build failed: Error: Parse Error: <h1 style=\"display:none\">{{title}}</h
1>\n\n<div class=\"container gt-container-fluid gt-container-form\">\n    <div c...
BenGWeeks commented 7 years ago

OK, looks like this works:

'use strict';

const gulp = require('gulp');
const build = require('@microsoft/sp-build-web');
var spsave = require('gulp-spsave');
var auth = require('./_private/settings');

// Ref: https://github.com/webpack/docs/wiki/configuration#outputpublicpath

build.configureWebpack.setConfig({
  additionalConfiguration: (config) => {
    var webpack = require('webpack');

    // Angular 2 fix, see: https://github.com/angular/angular/issues/10618
    // Remove the Microsoft-provided Uglify plugin
    // If you only want this to happen during a prod build, add the
    // following if statement:
    // if (build.getConfig().production) { ... }
    config.plugins.forEach((plugin) => {
      if (plugin instanceof webpack.optimize.UglifyJsPlugin) {
        var index = config.plugins.indexOf(plugin);
        config.plugins.splice(index, 1);
      }
    });
    // Add our custom config plugin
    config.plugins.push(new webpack.optimize.UglifyJsPlugin({
      beautify: false,
      mangle: false,
    }));

    //config.devtool = 'source-map';

    // Workaround for ng2, see: https://github.com/angular/material2/issues/1335#issuecomment-277157354
    config.htmlLoader = {
        minimize: false // workaround for ng2
    }

    config.module.loaders.push([
      { test: /\.(woff|woff2)$/, loader: "url-loader?limit=10000&mimetype=application/font-woff" },
      { test: /\.ttf$/, loader: "file-loader" },
      //{ test: /\.html$/, loader: "html-loader?-minimize" }, // workaround for ng2
      { test: /\.html$/, loader: "html?interpolate=require&-minimize" }, // workaround for ng2
      // { test: /\.html$/, loader: "html-loader", query: { minimize: false } }, // workaround for ng2
      { test: /\.eot$/, loader: "file-loader" },
      { test: /\.svg$/, loader: "file-loader" },
      { test: /\.scss$/, loaders: ["style-loader", "css-loader?sourceMap", "sass-loader?sourceMap"]}      
    ]);

    return config;
  }
});

build.initialize(gulp);

gulp.task('changeBase', function(){
 // gulp.src(['./dist/index.aspx'])
 //   .pipe(replace('<base href="/">', '<base href="/sites/Development/R2Dev/SitePages/ng2/index.aspx">'))
 //   .pipe(gulp.dest('./dist'));
});

gulp.task("spsave",['changeBase'], function () {
    return gulp.src(["./dist/**/*.*"])
        .pipe(spsave({
            siteUrl: auth.siteCollectionUrl,
            folder: "SiteAssets/GrantThornton",
            flatten: false
        }, auth));
});

And it's now giving a template error, but that would seem to be a separate issue:

Unhandled Promise rejection: Template parse errors:
Unexpected closing tag "legend" (">\n            <fieldset class=\"gt-fieldset\">\n                <legend class=\"gt-legend\">Details[ERROR ->]</legend>\n                <div class=\"row gt-row\">\n                    <div class=\"col-6\"><labe"): t@0:238
Unexpected closing tag "label" ("s=\"row gt-row\">\n                    <div class=\"col-6\"><label for=\"title\">Requirements Title:[ERROR ->]</label>

Where the template is (which looks fine to me?):

<div class="container gt-container-fluid gt-container-form">
    <div class="row">
        <div class="col-sm-6">
            <fieldset class="gt-fieldset">
                <legend class="gt-legend">Details</legend>
                <div class="row gt-row">
                    <div class="col-6"><label for="title">Requirements Title:</label></div>
                    <div class="col-6"><input id="title" type="text" class="k-textbox" [(ngModel)]="Requirement.Title"/></div>
                </div>
                <div class="row gt-row">
                    <div class="col-12"><label for="details">Requirements Details:</label></div>
                </div>
                <div class="row gt-row">
                    <div class="col-12">
                        <textarea id="details" class="k-textbox gt-textbox" [(ngModel)]="Requirement.Details"></textarea>
                    </div>
                </div>
                <div class="row gt-row">
                    <div class="col-6"><label for="rating">Requirement Rating:</label></div>
                    <div class="col-6"><kendo-dropdownlist id="ratings" [data]="ratingsData" [textField]="'ProductName'" [valueField]="'ProductID'" [defaultItem]="ratingsPlaceHolder"></kendo-dropdownlist></div>
                </div>
                <div class="row gt-row">
                    <div class="col-6"><label for="status">Approval Status:</label></div>
                    <div class="col-6"><kendo-dropdownlist id="approvalStatus" [data]=""></kendo-dropdownlist></div>
                </div>
            </fieldset>
            <fieldset class="gt-fieldset">
                <legend class="gt-legend">Attachments</legend>
                <div class="row gt-row">
                    <div class="col-12"><label for="attachments">Drag and drop files of click "Select" to browse:</label></div>
                </div>
                <div class="row gt-row">
                    <div class="col-12">
                        <kendo-upload
                            id="Attachments"
                            [saveUrl]=""
                            [removeUrl]=""
                            [disabled]="">
                        </kendo-upload>
                    </div>
                </div>
            </fieldset>
        </div>
        <div class="col-sm-6">
            <kendo-tabstrip>
                <kendo-tabstrip-tab [title]="'Framework Items'" [selected]="true">
                    <template kendoTabContent>
                        <div class="row gt-row">
                            <div class="col-6"><label for="framework">Framework Items:</label></div>
                            <div class="col-6"><kendo-multiselect [data]="frameworkItems" [value]="" [placeholder]="'Framework Items'"></kendo-multiselect></div>
                        </div>
                        <div class="row gt-row">
                            <div class="col-12 gt-col-addremovebuttons">
                                <button kendoButton (click)="onButtonClick()" [primary]="true">+</button>
                                <button kendoButton (click)="onButtonClick()" [primary]="true">-</button>
                            </div>
                        </div>
                        <div class="row gt-row">
                            <div class="col-12">
                                <kendo-grid [data]="frameworkItemsData" [height]="200">
                                    <kendo-grid-column field="FrameworkLocation" title="ID">
                                    </kendo-grid-column>
                                    <kendo-grid-column field="FrameworkTitle" title="Name">
                                    </kendo-grid-column>
                                </kendo-grid>
                            </div>
                        </div>
                    </template>
                </kendo-tabstrip-tab>
                <kendo-tabstrip-tab [title]="'Related Actions'">
                    <template kendoTabContent>
                        <div class="row gt-row">
                            <div class="col-6"><label for="actions">Related Actions:</label></div>
                            <div class="col-6"><kendo-multiselect [data]="actionItems" [value]="" [placeholder]="'Actions'"></kendo-multiselect></div>
                        </div>
                    </template>
                </kendo-tabstrip-tab>
             </kendo-tabstrip>
        </div>
    </div>
    <div class="row gt-row">
        <div class="col-12 gt-col-buttons">
            <button kendoButton (click)="saveChanges()" [primary]="true">Save</button>
            <button kendoButton (click)="onButtonClick()" [primary]="false">Edit</button>
            <button kendoButton (click)="deleteRecord()" [primary]="false">Delete</button>
            <button kendoButton (click)="onButtonClick()" [primary]="false">Close</button>
        </div>
    </div>
</div>

Thanks for the help :-)

iclanton commented 7 years ago

Sounds like you got this working. We'll work on making the build tools more easily configurable in future releases.

swissgamedev commented 6 years ago

Did you get a chance to work more on this? Are there now other options to disable uglify/minimize so one can debug the solution properly?

msft-github-bot commented 4 years ago

Issues that have been closed & had no follow-up activity for at least 7 days are automatically locked. Please refer to our wiki for more details, including how to remediate this action if you feel this was done prematurely or in error: Issue List: Our approach to locked issues