Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Webpack 4 configuring entry points and outputs (dist folder generated in each project folder)

The case is to have main folder 'Projects' and installed there all webpack 4 files with configs. Inside the 'Projects' folder are many folders like 'Project1', 'Project2', etc...I want to start from 'node_modules' entry point where webpack.config.js is and customize there further entry points like ./Project1/js/app.jsx, outputs like ./Project1/dist/js/main.js, same with scss and index.html, all generated in 'dist' folder. The thing is to have always only once installed node_modules in main 'Projects' folder.


the package.json:

{
  "name": "webpack4_example",
  "version": "1.0.0",
  "main": "index.js",
  "browserslist": ["last 2 versions"],
  "scripts": {
    "build": "webpack --mode production",
    "watch": "webpack --watch --mode development",
    "start": "webpack-dev-server --open --mode development"
  },
  "devDependencies": {
    "babel-core": "^6.26.3",
    "babel-loader": "^7.1.4",
    "babel-preset-env": "^1.7.0",
    "babel-preset-react": "^6.24.1",
    "babel-preset-stage-2": "^6.24.1",
    "css-loader": "^0.28.11",
    "html-loader": "^0.5.5",
    "html-webpack-plugin": "^3.2.0",
    "mini-css-extract-plugin": "^0.4.0",
    "node-sass": "^4.9.0",
    "postcss-loader": "^2.1.5",
    "prop-types": "^15.6.1",
    "react": "^16.3.2",
    "react-dom": "^16.3.2",
    "sass-loader": "^7.0.1",
    "webpack": "^4.8.3",
    "webpack-cli": "^2.1.3",
    "webpack-dev-server": "^3.1.4"
  }
}

webpack.config.js:

const path = require('path');
const HtmlWebPackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  entry: './Project1/js/app.jsx',                // customized entry point
  output: { 
    path: path.resolve(__dirname, 'dist'),  
    filename: './js/out.js'                     // generated ./Project1/dist/js/out.js
  },
  watch: true,
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader'
        }
      },
      {
        test: /\.html$/,
        use: [
          { 
            loader: 'html-loader',
            options: { minimize: true } 
          }
        ]
      },
      {
        test: /\.(png|jpe?g)/i,
        use: [
          {
            loader: 'url-loader',
            options: {
              name: './img/[name].[ext]',
              limit: 10000
            }
          },
          {
            loader: 'img-loader'
          }
        ]
      },
      {
        test: /\.scss$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          'postcss-loader',
          'sass-loader'
        ]
      }
    ]
  },
  plugins: [
    new HtmlWebPackPlugin({
      template: './Project1/index.html',     // not sure how to set these sections
      filename: 'index.html'
    }),
    new MiniCssExtractPlugin({
      filename: '[name].css',
      chunkFilename: '[id].css'
    })
  ]
};

.babelrc:

{
  "presets": ["env", "react", "stage-2"]
}

From what I understand without customized entry points webpack as default will search for 'Projects/src/...' for all files like scss, js, img, index.html, index.js to operate on them and will generate the 'Projects/dist' folder with all files generated.

The configuration form above compiles without errors but doesn't generate the 'dist' folder anywhere so I'm not sure the compile process is done properly anyway.

Would appreciate any suggestions and solutions

like image 713
PawełG Avatar asked Nov 07 '22 06:11

PawełG


1 Answers

SOLUTION (updated: added working watching files): ok, I've managed to get it work (starting point is where node_modules and other webpack4 config files are installed, here in Projects main folder)

Projects
   |__Project1
   |         |__js
   |         |   |__app.jsx
   |         |__dist       //desirable result, generated dist folder
   |         |     |__*     //all generated folders/files html, js, css, img
   |         |__index.ejs  //renamed from index.html
   |
   |__Project2  //etc, project folders
   |
   |__src // if without customized entry points it's default source
   |    |__folders like /_scss, /img, /js
   |    |__index.js
   |    |__index.ejs   //renamed index.html, used when no customized
   |                   //entry points are set, same as for all /src
   |
   |__node_modules
   |__.babelrc
   |__package.json
   |__webpack.config.js

.babelrc unchanged and same as above in previous post

in this example in Projects folder normally is created src folder with all files/folders to pass thru webpack4, in /src/index.js file must be present, it's for importing some other files

example of index.js

import style from "./_scss/main.scss";    //paths for Projects/src/...
import style from "./main.css";

package.json

{
  "name": "webpack4_example",
  "version": "1.0.0",
  "main": "index.js",            // the file explained just above
  "browserslist": ["last 2 versions"],
  "scripts": {
    "dev": "webpack --mode development ./Project1/js/app.jsx --output ./Project1/dist/js/main.js",
    "build": "webpack --mode production ./Project1/js/app.jsx --output ./Project1/dist/js/main.js",
    "watch": "webpack --watch --mode development",
    "start": "webpack-dev-server --mode development --open --watch-content-base ./Project1/js/app.jsx"  //watching desired files changes live in browser
  },
  "devDependencies": {
    "babel-core": "^6.26.3",
    "babel-loader": "^7.1.4",
    "babel-preset-env": "^1.7.0",
    "babel-preset-react": "^6.24.1",
    "babel-preset-stage-2": "^6.24.1",
    "css-loader": "^0.28.11",
    "html-loader": "^0.5.5",
    "html-webpack-plugin": "^3.2.0",
    "mini-css-extract-plugin": "^0.4.0",
    "node-sass": "^4.9.0",
    "postcss-loader": "^2.1.5",
    "prop-types": "^15.6.1",
    "react": "^16.3.2",
    "react-dom": "^16.3.2",
    "sass-loader": "^7.0.1",
    "webpack": "^4.8.3",
    "webpack-cli": "^2.1.3",
    "webpack-dev-server": "^3.1.4"
  }
}

where --mode production | developement | none means formatting optimizations for the output files in dist folder or none of such optimizations, for readibility use none

webpack.config.js

const HtmlWebPackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  module: {
    rules: [
      {
        test: /\.(js$|jsx$)/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader'
        }
      },
      {
        test: /\.html$/,
        use: [
          { 
            loader: 'html-loader',
            options: { minimize: true } 
          }
        ]
      },
      {
        test: /\.(png|jpe?g)/i,
        use: [
          {
            loader: 'url-loader',
            options: {
              name: './img/[name].[ext]',
              limit: 10000
            }
          },
          {
            loader: 'img-loader'
          }
        ]
      },
      {
        test: /\.(css$|scss$)/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          'postcss-loader',
          'sass-loader'
        ]
      }
    ]
  },
  plugins: [
    new HtmlWebPackPlugin({
      template: './Project1/index.ejs',     // entry point for html
      filename: 'index.html'
    }),
    new MiniCssExtractPlugin({
      filename: '[name].css',
      chunkFilename: '[id].css'
    })
  ],
  watchOptions: {                   //added to make possible watch files
    ignored: /node_modules/,
    aggregateTimeout: 300,
    poll: 1000
  }
};

the customized entry point for index.html where .html extension is changed to .ejs as for working around some issues caused between html-loader and html-webpack-plugin. With .ejs the output html, also placed in dist folder automatically, isn't optimized with formatting and is readible. Watch out if html.ejs contains tag with pinned path for [out].js file (here the one generated in dist folder). The generated index.html from dist folder will add another such line so it will be doubled -> line to delete.

for run use: npm run build, npm start

like image 187
PawełG Avatar answered Nov 14 '22 23:11

PawełG