webpack 4

1. Default


mkdir webpack4-boilerplate
cd webpack4-boilerplate
yarn init -y
yarn add webpack webpack-cli -D
            

2. Структура проекта

3. Тест


src/index.js
console.log('Hello World')
               

3-a. Запуск


yarn run webpack
               

3-b. Результат


dist/main.js
               

4. index.html


touch dist/index.html
                

emmet: !

<script src="./main.js"></script>

Browser WebConsole: 'Hello World'

4-a. По умолчанию:

  1. Сборка ES6 modules
    
    index.js
    import { hello } from './hello'
    import { log } from './log'
    
    document.body.insertAdjacentHTML(
        'afterbegin', 
        `<h1>${hello}</h1>`
    )
    log(hello)
    
    hello.js
    export const hello = "Hello World!";
    
    log.js
    export const log = msg => console.log(msg)
                            
  2. Файл index.html подключает main.js и любые другие ресурсы по желанию без Webpack.

5. webpack.config.js

  1. entry
  2. output
  3. loader
  4. plugins

module.exports - объект конфигурации webpack

5.1. entry & output


const path = require("path");

module.exports = {
    entry: "./src/index.js" ,
    output: {
      path: path.resolve(__dirname, "dist"),
      filename: "bundle.js",
    }
}
               

5.2. Plugins

Переместите dist/index.html в src/index.html

6. webpack-dev-server


package.json
 "scripts": {
    "build": "webpack --mode production",
    "start": "webpack-dev-server  --mode development"
  },
               

yarn add  webpack-dev-server -D

webpack.config.js
module.exports = {
entry & output
    devServer: {
        contentBase: path.join(__dirname, "dist"),
        port: 8080,
        overlay: {
        warnings: false,
        errors: true
        }
    }
}
               

contentBase - указывает на абсолютный путь к папкам которые будут отслеживаться

port - изменить номер порта

overlay - вывод errors: true на web-страницу и игнорирование warning

Подробное описание webpack-dev-server

7. Debagger & Devtool

Контроль за отображением source maps в debagger браузеров


webpack.config.js
const conf = {
    содержимое module.exports
}

module.exports = (env, options) => {
    const production = options.mode === "production";
    conf.devtool = production
        ? "source-map"
        : "eval-sourcemap";
    return conf;
  };
               

Подробнее о devtool

Пример настройки webpack.config.js

Важно: в debagger пока не видно файла log.js

8. Loaders


const conf = {
  module: {
    rules: [ {
 loaders
    } ]
  }
}
            
  1. test - регулярное выражение, описывающее к каким файлам применяется loader
  2. exclude или include - регулярное выражение, исключающее или включающее дополнительные условия отбора
  3. use - объект или массив объектов со свойством loader и необязательными дополнительными свойствами
  4. options: {fallback: "reserve-loader"} - использование резервного зарузчика в случае проблем работы основного
    
    use: {
      loader: "main-loader",
      options: {
        fallback: "reserve-loader"
      }
    }
                

Список основных loader с описанием и примерами

8.1 Loaders: Babel


yarn add @babel/core babel-loader @babel/preset-env -D
          

test: /\.js$/,
exclude: /node_modules/,
use: {
  loader: "babel-loader",
  options: {
    presets: ["@babel/preset-env"]
  }
}

Важно: в debagger теперь видно файл log.js

Подробнее об инсталяции babel

Подробнее о babel-loader

8.3. Loaders: File

Добавим в src папку image и поместим туда изображение.

Попробуем добавить это изображение как фоновое в CSS/SASS файл указав путь от css/scss файла к изображению:


background: url(../image/foto.jpg);
        

Ошибка с текстом "You may need an appropriate loader to handle this file type." подсказывает, что необходим новый loader.


yarn add file-loader  -D

webpack.config.js
test: /\.(png|jpg|gif|svg)$/,
  use: [
    {
      loader: 'file-loader',
      options: {}
    }
  ]
        

Подходит для загрузки файлов, подключаемых через CSS/SASS - шрифты, изображения

Для изображений существует несколько различных loader - раздел 8.3 - 8.4.

file-loader подходит для работы с подготовленными (оптимизированными) изображеними.

Что делает file-loader: название файла заменяет на хеш-строку вида "447fbeb86e3d496c33cd32a563ce612a.jpg", а сам файл и ссылку на него размещает в dist

Сохранение пути и имени файла возможно с помощью options


webpack.config.js
options: {
  name: '[path][name].[ext]',
  context: ''
}

src/scss/style.scss
background: url(../../asssets/image/foto.jpg);

dist/style.css
background: url(asssets/image/foto.jpg);
        

Подробнее о file-loader

8.2 Loaders: CSS/SASS


yarn add style-loader -D
yarn add css-loader -D
yarn add sass-loader -D
yarn add node-sass -D
          
  1. Важен порядок подключения
  2. Последовательность выполнения в массиве - с конца к началу массива
    Пример метода pop()
     
    let str = '';
    let arr = ['style-loader', 'css-loader'];
    
    while (arr.length) {
       str +=   arr.pop() + "; \n";
    }
    
    css-loader;
    style-loader;
    
              
  3. Sass-loader считывает файлы, формирует css, передает следующему лоадеру в массиве
  4. Css-loader получает (или считывает файлы в отсутствие sass) и передает следующему лоадеру
  5. Style-loader помещает css в head index.html в теге style

test: /\.scss$/,
use: [
  { loader: "style-loader" },
  {
    loader: "css-loader",
    options: {
      modules: false
    }
  },
  {
    loader: "sass-loader",
    options: {
      sourceMap: true
    }
  }
]
          

8.2-a. Подключение файлов sass/css

Файлы подключаются в *.js файлы с помощью import


src/scss/style.scss
h1 {
    text-align: center;
    font-family: sans-serif;
    color: #c00;
}

index.js
import './scss/style.scss';
          

После запуска проверить header файла index.html

5.3. Plugin: отдельный css файл


yarn add extract-css-chunks-webpack-plugin -D

webpack.config.js
const ExtractCssChunks 
  = require("extract-css-chunks-webpack-plugin");

rules: 
[
  { loader: "style-loader" },
  { loader: ExtractCssChunks.loader },
  { loader: "css-loader"}
]

plugins: 
 new ExtractCssChunks({
      filename: "style.css",
      chunkFilename: "[id].css",
      hot: true,
      orderWarning: true,
      reloadAll: true,
      cssModules: false
    }),

index.html
<link rel="stylesheet" href="./style.css">
          

8.3. Loaders: Url

Изображение меньше определенного размера можно преобразовать в DataURL формат. Изображения большего размера будут обработаны как file-loader


yarn add url-loader -D

webpack.config.js
test: /\.(png|svg|jpg|gif)$/,
use: [
  {
    loader: "url-loader",
    options: {
      fallback: "file-loader",
      name: "[path][name].[ext]",
      outputPath: "img/",
      limit: 8192
    }
  }
]
            

8.4. Loaders: svg, оптимизация и т.п.

SVG

Оптимизация

srcset

8.5. Loaders: Handlebars

Пример подключения Handlebars


yarn add handlebars-loader -D
yarn add handlebars --save

webpack.config.js
test: /\.hbs$/,
use: "handlebars-loader",
exclude: /node_modules/

index.js
import  headerRun  from "./js/header";
export const wrapper = document.querySelector(".wrapper");
headerRun();

js/header.js
import headerTpl from '../html/header.hbs';
import { wrapper } from "../index";
const data = {
    title: 'Handlebars'
};
export default function run () {
    wrapper.insertAdjacentHTML(
      "afterbegin",
      headerTpl(data)
      );
}

html/header.hbs
<h2>{{title}}</h2>
            

Готовая сборка: Webpack 4 + Bootstrap 4 + Handlebars

Дополнительно

Подробный обзор webpack

Laravel: