Skip to content

Latest commit

 

History

History
283 lines (232 loc) · 5.73 KB

课时-02.md

File metadata and controls

283 lines (232 loc) · 5.73 KB

课题 02:搭建可插拔的开发环境跟生产环境

本章提要:

│── build
   │── base.js                 // 公共部分
   │── build.js
   └── dev.js
│── config
   │── base.js                 // 基础配置
   │── css.js                  // css 配置
   │── HtmlWebpackPlugin.js    // html 配置
   └── MiniCssExtractPlugin.js // 提取css
│── public                      // 公共资源
   └── index.html              // html 模版
└── src                         // 开发目录
    │── style
     └── index.css
    └── main.js                // 主入口

package.json

{
  "scripts": {
    "dev": "cross-env NODE_ENV=development node build/dev.js",
    "build": "cross-env NODE_ENV=production node build/build.js"
  },
  "dependencies": {
    "cross-env": "^6.0.3",
    "css-loader": "^3.2.0",
    "cssnano": "^4.1.10",
    "ora": "^4.0.3",
    "rimraf": "^3.0.0",
    "webpack": "^4.41.2"
  },
  "devDependencies": {
    "extract-text-webpack-plugin": "^3.0.2",
    "html-webpack-plugin": "^3.2.0",
    "mini-css-extract-plugin": "^0.8.0",
    "vue-cli-plugin-commitlint": "^1.0.4",
    "webpack-chain": "^6.0.0",
    "webpack-cli": "^3.3.10",
    "webpack-dev-server": "^3.9.0"
  }
}

build/base.js

const { findSync } = require("../lib");
const Config = require("webpack-chain");
const config = new Config();
const files = findSync("config");
const path = require("path");
const resolve = p => {
  return path.join(process.cwd(), p);
};

module.exports = () => {
  const map = new Map();

  files.map(_ => {
    const name = _.split("/")
      .pop()
      .replace(".js", "");
    return map.set(name, require(_)(config, resolve));
  });

  map.forEach(v => v());

  return config;
};

build/build.js

const rimraf = require("rimraf");
const ora = require("ora");
const chalk = require("chalk");
const path = require("path");
// 删除 dist 目录
rimraf.sync(path.join(process.cwd(), "dist"));

const config = require("./base")();
const webpack = require("webpack");
const spinner = ora("开始构建项目...");
spinner.start();

webpack(config.toConfig(), function(err, stats) {
  spinner.stop();
  if (err) throw err;
  process.stdout.write(
    stats.toString({
      colors: true,
      modules: false,
      children: false,
      chunks: false,
      chunkModules: false
    }) + "\n\n"
  );

  if (stats.hasErrors()) {
    console.log(chalk.red("构建失败\n"));
    process.exit(1);
  }

  console.log(chalk.cyan("build完成\n"));
});

build/dev.js

const config = require("./base")();
const webpack = require("webpack");
const chalk = require("chalk");
const WebpackDevServer = require("webpack-dev-server");
const port = 8080;
const publicPath = "/common/";

config.devServer
  .quiet(true)
  .hot(true)
  .https(false)
  .disableHostCheck(true)
  .publicPath(publicPath)
  .clientLogLevel("none");

const compiler = webpack(config.toConfig());
// 拿到 devServer 参数
const chainDevServer = compiler.options.devServer;
const server = new WebpackDevServer(
  compiler,
  Object.assign(chainDevServer, {})
);

["SIGINT", "SIGTERM"].forEach(signal => {
  process.on(signal, () => {
    server.close(() => {
      process.exit(0);
    });
  });
});
// 监听端口
server.listen(port);

new Promise(() => {
  compiler.hooks.done.tap("dev", stats => {
    const empty = "    ";
    const common = `App running at:
    - Local: http://127.0.0.1:${port}${publicPath}\n`;
    console.log(chalk.cyan("\n" + empty + common));
  });
});

config/css.js

css 提取 loader 配置

module.exports = (config, resolve) => {
  return (lang, test) => {
    const baseRule = config.module.rule(lang).test(test);
    const normalRule = baseRule.oneOf("normal");
    applyLoaders(normalRule);
    function applyLoaders(rule) {
      rule
        .use("extract-css-loader")
        .loader(require("mini-css-extract-plugin").loader)
        .options({
          publicPath: "./"
        });
      rule
        .use("css-loader")
        .loader("css-loader")
        .options({});
    }
  };
};

css 提取插件 MiniCssExtractPlugin

config/MiniCssExtractPlugin.js

const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = (config, resolve) => {
  return () => {
    config
      .oneOf("normal")
      .plugin("mini-css-extract")
      .use(MiniCssExtractPlugin);
  };
};

config/HtmlWebpackPlugin.js

const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = (config, resolve) => {
  return () => {
    config.plugin("html").use(HtmlWebpackPlugin, [
      {
        template: "public/index.html"
      }
    ]);
  };
};

测试 html 模板

public/index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>learn_webpack</title>
  <body></body>
</html>

测试 css 模板

src/style/index.css

.test {
  width: 200px;
  height: 200px;
  color: red;
  background-color: orange;
}

程序入口

src/main.js

require("./style/index.css");

const h2 = document.createElement("h2");
h2.className = "test";
h2.innerText = "test";
document.body.append(h2);