symfony / webpack-encore

A simple but powerful API for processing & compiling assets built around Webpack
https://symfony.com/doc/current/frontend.html
MIT License
2.23k stars 197 forks source link

Webpack compilation for legacy projects #273

Open hanishsingla opened 6 years ago

hanishsingla commented 6 years ago

Hi,

Many projects here are on SF3 and almost everyone want to consider SF4 upgrade. But there is a hit for many of them. Most of the templates are not much compatible with Webpack as they have ES5 code. In SF3, Assetic did work for minification and concatenation of assets. But Assetic is removed in SF4. So in that case, everyone is left with 2 choices, keep themselves limited to SF3 or rebuild everything as ES6 standards with Webpack.

IMHO, there should be some option to just concatenate the js files and keep everything working. We can refer to Laravel Mix feature for same situation. You can check it on https://laravel.com/docs/5.6/mix -> Vanilla JS. I think a feature similar to "mix.scripts()" can avoid many issues and increase ease to adopt Webpack Encore.

Please let us know if there is already some feature which can be used in above situation. We may need spread more awareness on it then.

Lyrkan commented 6 years ago

Hi @hanishsingla,

Sorry for the late answer but you probably could do that by adding the webpack-concat-plugin with Encore.addPlugin.

We could also probably add a helper method to do that but sadly that can't be done for now for the same reason #221 (which copy files instead of concatenating them) hasn't been merged yet: it would work but the resulting files won't be present in the manifest.json file (see #140).

hanishsingla commented 6 years ago

It worked for me as following:

  1. add webpack-concat-plugin (I am using yarn) yarn add webpack-concat-plugin

  2. Require instance of webpack-concat-plugin in webpack.config.js var ConcatPlugin = require("webpack-concat-plugin");

  3. Use this webpack-concat-plugin to build js files as follows:

    .addPlugin(
    new ConcatPlugin({
      uglify: Encore.isProduction(),
      sourceMap: false,
      name: "breakpoints",
      outputPath: "js/",
      fileName: "[name].js",
      filesToConcat: [
        "./web/public/vendor/modernizr/modernizr.js",
        "./web/public/vendor/breakpoints/breakpoints.js"
      ],
      attributes: {
        async: true
      }
    })
    )

    This is working fine so far.

weaverryan commented 6 years ago

Thanks for sharing this :).

In addition to using concatenation, we have a section about legacy applications on the docs, but perhaps it need to be extended: https://symfony.com/doc/4.0/frontend/encore/legacy-apps.html

Basically, if you still have JavaScript in your template, that's fine. You'll just need to create one entry point that is included on every page, and make sure you expose whatever global variables you need - e.g.

// require jQuery normally
const $ = require('jquery');

// create global $ and jQuery variables
global.$ = global.jQuery = $;

We did this quite a lot for our upgrade on KnpUniversity - once you expose all the globals you need, your template code is perfectly happy :). Then you can upgrade (remove the JavaScript from the template) over time.

Cheers!