Prestashop 1.7.1 | Use Webpack in Classic theme

November 13th, 2017

This time i need to compile the prestashop “Classic” theme.
PrestaShop 1.7 is using Webpack Module Bundler to manage assets in PrestaShop front.
Webpack takes modules with dependencies and generates static assets representing those modules.

Before install Webpack we need to install node.js, for do that, go to https://nodejs.org/en/, and download the installer.
Once downloaded, install it.

Now donwload a clean and updated version of classic theme form github;

https://github.com/PrestaShop/PrestaShop/archive/1.7.2.4.zip
Extract “Classic” folder, and replace the one on your prestashop.

Now using NMP Package manager you can install webpack.

Install Webpack in PrestaShop/themes/classic/_dev folder.
Now you need to install some modules of Webpack.

npm install --save-dev style-loader 
npm install --save-dev css-loader 
npm install --save-dev babel-loader 
npm install --save-dev postcss-loader

If all work fine, you can see the folder ‘node_modules’ in your _dev folder.
That’s meening that all is installed.
From now, .scss and .js that are stored in _dev folder are compiled.
To build your assets once,

npm run build

To rebuild your assets every time you change a file in the _dev folder

npm run watch

.

BEST PRACTICES

Often, prestashop’s update, update theme files too, so, if you added your custom .scss to the theme.scss, you risk to lose all your modifies.

Is best practice add your own custom.scss to the compiled .css.
For do that, open your webpack.config.js,

const webpack = require('webpack');
const path = require('path');
const ExtractTextPlugin = require("extract-text-webpack-plugin");

let config = {
  entry: {
    main: [
      './js/theme.js',
      './css/theme.scss'
    ]
  },
  output: {
    path: path.resolve(__dirname, '../assets/js'),
    filename: 'theme.js'
  },
  module: {
    rules: [
      {
        test: /\.js/,
        loader: 'babel-loader'
      },
      {
        test: /\.scss$/,
        use: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: [
            {
              loader: 'css-loader',
              options: {
                minimize: true
              }
            },
            'postcss-loader',
            'sass-loader'
          ]
        })
      },
      {
        test: /.(png|woff(2)?|eot|ttf|svg)(\?[a-z0-9=\.]+)?$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: '../css/[hash].[ext]'
            }
          }
        ]
      },
      {
        test : /\.css$/,
        use: ['style-loader', 'css-loader', 'postcss-loader']
      }
    ]
  },
  externals: {
    prestashop: 'prestashop',
    $: '$',
    jquery: 'jQuery'
  },
  plugins: [
    new ExtractTextPlugin(path.join('..', 'css', 'theme.css'))
  ]
};

config.plugins.push(
  new webpack.optimize.UglifyJsPlugin({
    sourceMap: false,
    compress: {
      sequences: true,
      conditionals: true,
      booleans: true,
      if_return: true,
      join_vars: true,
      drop_console: true
    },
    output: {
      comments: false
    },
    minimize: true
  })
);

module.exports = config;

Modify this snippet, by adding your custom.scss ( custom.scss it can be anything with extension .scss ), the only important thing is that your custom.css is in the ” yourthemes/_dev/css ” folder.

entry: {
    main: [
      './js/theme.js',
      './css/theme.scss',
      './css/custom.scss'
    ]
  },

Save, add some scss rules on you custom.scss and rebuild your assets.

npm run build

Now the code on your custom.scss was added to compiled theme.css ( yourthemes/assets/css/ ).

If you need to update the theme, simply you can follow same procedure, and copy the modified files .tpl from old theme to new one.