如何在 Drupal 项目中使用 Webpack 设置实时重新加载和编译资产?

How to setup live reloading and assets compiling with Webpack in a Drupal project?

到目前为止,我已经能够设置 Webpack 来编译 Sass 和 JavaScript。我在名为 amazon.

的 Drupal 自定义主题中分别编译 styles.scssindex.js 放置在 assets/scss/assets/js/ 文件夹中

我在 assets/dist/ 文件夹中生成了一个 styles.css 和一个 index.js。这些都包含在我的 Twig 模板中 amazon.libraries.yml.

有没有办法同时进行实时重新加载?至于现在我的资产在每次更改后都会重新编译,但我必须手动重新加载浏览器。我正在使用 Drupal v8.9.20 和 Node.js v16.15.0.

assets/js/index.js:

import "../scss/styles.scss";
console.log("Hello World");

package.json:

{
  "name": "amazon",
  "scripts": {
    "start": "webpack",
    "build": "MODE=production webpack"
  },
  "devDependencies": {
    "@babel/core": "^7.14.6",
    "@babel/preset-env": "^7.14.7",
    "autoprefixer": "^10.4.7",
    "babel-loader": "^8.2.2",
    "css-loader": "^6.0.0",
    "css-minimizer-webpack-plugin": "^3.0.2",
    "mini-css-extract-plugin": "^2.1.0",
    "postcss-loader": "^6.1.1",
    "postcss-preset-env": "^7.6.0",
    "sass": "^1.52.1",
    "sass-loader": "^12.1.0",
    "webpack": "^5.49.0",
    "webpack-cli": "^4.9.1"
  }
}

webpack.config.js:

const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const target = process.env.MODE === "production" ? "browserslist" : "web";
const mode = process.env.MODE === "production" ? "production" : "development";
module.exports = {
  entry: "./assets/js/index.js",
  output: {
    path: path.resolve(__dirname, "assets/dist"),
    filename: "index.js",
  },
  module: {
    rules: [
      {
        test: /\.s[ac]ss$/i,
        use: [
          MiniCssExtractPlugin.loader,

          {
            loader: "css-loader",
            options: {
              url: false,
            },
          },
          {
            loader: "postcss-loader",
            options: {
              postcssOptions: {
                plugins: [["postcss-preset-env"]],
              },
            },
          },
          {
            loader: "sass-loader",
            options: {
              implementation: require("sass"),
            },
          },
        ],
      },

      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
          options: {
            presets: ["@babel/preset-env"],
          },
        },
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: "styles.css",
    }),
  ],
  optimization: {
    minimizer: ["...", new CssMinimizerPlugin()],
  },
  target: target,
  devtool: mode == "production" ? false : "source-map",
  mode: mode,
  watch: mode !== "production",
};

.browserslistrc:

defaults

我可以使用 BrowserSync 设置实时重新加载。我正在使用我的 Drupal 开发代理 BrowserSync url (localhost:3000) url (amazon.test).

问题的设置是一个好的开始,如下更改 package.jsonwebpack.config.js,运行 npm i,然后 npm start

package.json:

{
  "name": "amazon",
  "scripts": {
    "start": "webpack",
    "build": "MODE=production webpack"
  },
  "devDependencies": {
    "@babel/core": "^7.14.6",
    "@babel/preset-env": "^7.14.7",
    "autoprefixer": "^10.4.7",
    "babel-loader": "^8.2.2",
    "browser-sync": "^2.27.10",
    "browser-sync-webpack-plugin": "^2.3.0",
    "css-loader": "^6.0.0",
    "css-minimizer-webpack-plugin": "^3.0.2",
    "mini-css-extract-plugin": "^2.1.0",
    "postcss-loader": "^6.1.1",
    "postcss-preset-env": "^7.6.0",
    "sass": "^1.52.1",
    "sass-loader": "^12.1.0",
    "webpack": "^5.49.0",
    "webpack-cli": "^4.9.1"
  }
}

webpack.config.js:

const path = require("path");
const BrowserSyncPlugin = require("browser-sync-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const target = process.env.MODE === "production" ? "browserslist" : "web";
const mode = process.env.MODE === "production" ? "production" : "development";
module.exports = {
  mode,
  watch: mode !== "production",
  entry: "./assets/js/index.js",
  output: {
    path: path.resolve(__dirname, "assets/dist"),
    filename: "index.js",
  },
  module: {
    rules: [
      {
        test: /\.s[ac]ss$/i,
        use: [
          MiniCssExtractPlugin.loader,

          {
            loader: "css-loader",
            options: {
              url: false,
            },
          },
          {
            loader: "postcss-loader",
            options: {
              postcssOptions: {
                plugins: [["postcss-preset-env"]],
              },
            },
          },
          {
            loader: "sass-loader",
            options: {
              implementation: require("sass"),
            },
          },
        ],
      },

      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
          options: {
            presets: ["@babel/preset-env"],
          },
        },
      },
    ],
  },
  plugins: [
    new BrowserSyncPlugin(
      // BrowserSync options
      {
        // browse to http://localhost:3000/ during development
        host: "localhost",
        port: 3000,
        proxy: "amazon.test", // change to your own development url
        files: [
          {
            match: ["**/*.php"],
          },
          {
            match: ["templates/*.twig"],
          },
          {
            match: ["**/*.js"],
          },
          {
            match: ["**/*.scss"],
          },
          {
            match: ["**/*.png"],
          },
          {
            match: ["**/*.jpeg"],
          },
          {
            match: ["**/*.jpg"],
          },
          {
            match: ["**/*.svg"],
          },
        ],
        notify: false,
      },
      // plugin options
      {
        reload: true,
      }
    ),
    new MiniCssExtractPlugin({
      filename: "styles.css",
    }),
  ],
  optimization: {
    minimizer: ["...", new CssMinimizerPlugin()],
  },
  target: target,
  devtool: mode == "production" ? false : "source-map",
};