40·灵魂前端工程师养成-前端框架webpack

2022-09-26 17:23:11 浏览数 (1)

  • 前置知识
  • 安装webpack
  • webpack模式
  • webpack添加js
  • webpack生成html
  • webpack引入css
  • webpack dev server代替http-server
  • webpack提取CSS文件
  • webpack使用多配置文件
  • webpack引入scss
  • webpack引入LESS和Stylus
  • webpack引入图片

-曾老湿, 江湖人称曾老大。


-多年互联网运维工作经验,曾负责过大规模集群架构自动化运维管理工作。 -擅长Web集群架构与自动化运维,曾负责国内某大型金融公司运维工作。 -devops项目经理兼DBA。 -开发过一套自动化运维平台(功能如下): 1)整合了各个公有云API,自主创建云主机。 2)ELK自动化收集日志功能。 3)Saltstack自动化运维统一配置管理工具。 4)Git、Jenkins自动化代码上线及自动化测试平台。 5)堡垒机,连接Linux、Windows平台及日志审计。 6)SQL执行及审批流程。 7)慢查询日志分析web界面。


前置知识


ES6的使用

let const 箭头函数 new ...操作符 class Promise 继承 this 原型


CSS语法和布局

flex布局 grid布局 绝对定位 相对定位


MVC概念

Model View Controller EventHub


工具的使用

VScode WebStorm 终端命令: - npm - yarn - http-server - parcel - git

安装webpack


进入官网安装

webpack官网:TP

代码语言:javascript复制
MacBook-pro:~ driverzeng$ npm info webpack

代码语言:javascript复制
# 安装webpack的4版本
MacBook-pro:~ driverzeng$ npm i -g webpack@4 webpack-cli@4

webpack的作用

转译代码(ES6转译为ES5,SCSS转译为CSS) 构建build 代码压缩 代码分析


创建项目

代码语言:javascript复制
# 创建webpack项目目录
MacBook-pro:HTML driverzeng$ mkdir webpack-demo-1

# 用VScode打开,windows可以拖进VScode
MacBook-pro:HTML driverzeng$ code webpack-demo-1/

# 打开后新建终端,在VScode中执行(创建package.json)
MacBook-pro:webpack-demo-1 driverzeng$ npm  init -y

代码语言:javascript复制
# 安装webpack用npm
MacBook-pro:webpack-demo-1 driverzeng$ npm install webpack webpack-cli --save-dev

# 安装webpack用yarn
MacBook-pro:webpack-demo-1 driverzeng$ yarn global add webpack webpack-cli --save-dev

安装完会出现一个node_model


创建JS文件


使用webpack转译JS

代码语言:javascript复制
MacBook-pro:webpack-demo-1 driverzeng$ npx webpack ./src/main.js 

webpack模式


开发环境or生产环境

代码语言:javascript复制
// 如果是开发阶段那就用development模式
module.exports = {
    mode: 'development'
};

// 如果要发布上线,那就用production
module.exports = {
    mode: 'production'
};

webpack添加js


与hash结合

这回添加一个,输出文件名,这样的话,我们就可以根据文件内容产生对应hash的文件名,如此做的原因是因为HTTP缓存,

代码语言:javascript复制
module.exports = {
    mode: 'production',
    entry: './src/index.js',
    output: {
      filename:'[name].[contenthash].js'
    }
};

现在我们修改一下,index.js的内容,重新构建一下。

代码语言:javascript复制
MacBook-pro:webpack-demo-1 driverzeng$ npx webpack

如此一来,每次一更新就会多创建一个文件,所以我们需要在build之前删除dist目录.修改package.json文件,加一行build的内容

代码语言:javascript复制
{
  "name": "webpack-demo-1",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "rm -fr dist && npx webpack",
    "test": "echo "Error: no test specified" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "webpack": "^4.43.0",
    "webpack-cli": "^3.3.11"
  }
}

从今以后,我们只需要运行下面的代码,进行build

代码语言:javascript复制
MacBook-pro:webpack-demo-1 driverzeng$ yarn build

webpack生成html


使用webpack生成html

代码语言:javascript复制
// 安装html-webpack-plugin这个插件
MacBook-pro:webpack-demo-1 driverzeng$ yarn add html-webpack-plugin --dev

修改webpack配置文件

webpack.config.js

代码语言:javascript复制
var HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
    mode: 'production',
    entry: './src/index.js',
    output: {
      filename:'[name].[contenthash].js'
    },
    plugins:[new HtmlWebpackPlugin()]
};

接下来,我们build试一下

代码语言:javascript复制
MacBook-pro:webpack-demo-1 driverzeng$ yarn build

辣么,问题又来了,生成那个html有什么用呢?就一个body,然后里面引入一个js文件,也不能往里面写东西,如果写了,下一次build,会自动覆盖跟没写一样...

肿么办呢?

当然是修改webpack的配置文件啦。

代码语言:javascript复制
var HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
  mode: "production",
  entry: "./src/index.js",
  output: {
    filename: "[name].[contenthash].js",
  },
  plugins: [
    new HtmlWebpackPlugin({
      title: "DriverZeng - zls",
    }),
  ],
};

构建一下试试

由此可见,我们改了title,接下来实现,我们在里面添加div

代码语言:javascript复制
var HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
  mode: "production",
  entry: "./src/index.js",
  output: {
    filename: "[name].[contenthash].js",
  },
  plugins: [
    new HtmlWebpackPlugin({
      title: "DriverZeng - zls",
      template: "src/assets/index.html",
    }),
  ],
};

继续改配置文件,改完之后,在目录下创建一个assets目录,然后创建index.html

代码语言:javascript复制
<!DOCTYPE html>
<html lang="zh">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">
    <title>Document</title>
</head>

<body>
    <div id="zls1"></div>
</body>

</html>

构建一下

div加进去了,并且我们刚才还复制了淘宝的meta vp

构建完,自动添加了scripts,但是...title没有改变,继续改,只要把title那里改成变量即可

代码语言:javascript复制
<!DOCTYPE html>
<html lang="zh">

<head>
    <meta charset="UTF-8">
    <meta name="viewport"
        content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">
    <title><%= htmlWebpackPlugin.options.title %></title>
</head>

<body>
    <div id="zls1"></div>
</body>

</html>

webpack引入css


创建一个CSS文件

构建一下

报错了,webpack不认识CSS,所以我们需要安装一个css loader插件

代码语言:javascript复制
MacBook-pro:webpack-demo-1 driverzeng$ yarn add css-loader style-loader --dev

安装完之后,还得修改webpack的配置文件

代码语言:javascript复制
var HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
  mode: "production",
  entry: "./src/index.js",
  output: {
    filename: "[name].[contenthash].js",
  },
  plugins: [
    new HtmlWebpackPlugin({
      title: "DriverZeng - zls",
      template: "src/assets/index.html",
    }),
  ],
  module: {
    rules: [
      {
        test: /.css$/i,
        use: ["style-loader", "css-loader"],
      },
    ],
  },
};

修改完毕,我们再build一次

代码语言:javascript复制
MacBook-pro:webpack-demo-1 driverzeng$ yarn build

build过后,没有什么奇特的地方,我们进入dist目录,用http-server运行一下,看看页面是什么样子的

代码语言:javascript复制
MacBook-pro:webpack-demo-1 driverzeng$ cd dist/
MacBook-pro:dist driverzeng$ http-server -c-1

webpack dev server代替http-server


修改配置文件

如果想要用这个功能,我们首先要安装插件

代码语言:javascript复制
MacBook-pro:dist driverzeng$ yarn add webpack-dev-server --dev

然后把mode改成development环境,添加devtools

代码语言:javascript复制
var HtmlWebpackPlugin = require("html-webpack-plugin");
var path = require('path')

module.exports = {
  mode: "development",
  devtool: "inline-source-map",
  entry: "./src/index.js",
  output: {
    filename: "[name].[contenthash].js",
  },
  plugins: [
    new HtmlWebpackPlugin({
      title: "DriverZeng - zls",
      template: "src/assets/index.html",
    }),
  ],
  module: {
    rules: [
      {
        test: /.css$/i,
        use: ["style-loader", "css-loader"],
      },
    ],
  },
};

最后,我们再添加devserver

代码语言:javascript复制
var HtmlWebpackPlugin = require("html-webpack-plugin");
var path = require("path");

module.exports = {
  mode: "development",
  devtool: "inline-source-map",
  devServer: {
      contentBase: './dist',
  },
  entry: "./src/index.js",
  output: {
    filename: "[name].[contenthash].js",
  },
  plugins: [
    new HtmlWebpackPlugin({
      title: "DriverZeng - zls",
      template: "src/assets/index.html",
    }),
  ],
  module: {
    rules: [
      {
        test: /.css$/i,
        use: ["style-loader", "css-loader"],
      },
    ],
  },
};

然后再在package.json中添加一个命令

代码语言:javascript复制
{
  "name": "webpack-demo-1",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "webpack-dev-server --open",
    "build": "rm -fr dist && npx webpack",
    "test": "echo "Error: no test specified" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "style-loader": "^1.2.1",
    "webpack": "^4.43.0",
    "webpack-cli": "^3.3.11"
  },
  "devDependencies": {
    "css-loader": "^3.5.3",
    "html-webpack-plugin": "^4.3.0",
    "webpack-dev-server": "^3.11.0"
  }
}

然后我们运行 yarn start 或者 npm start,就会自动打开浏览器

然后我们修改代码,把背景改为蓝色,就会自动build

webpack提取CSS文件

目前CSS是标签,我们需要把它们抽成文件


安装插件

代码语言:javascript复制
MacBook-pro:dist driverzeng$ yarn add mini-css-extract-plugin --dev

修改配置文件

代码语言:javascript复制
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const path = require("path");

module.exports = {
  mode: "development",
  devtool: "inline-source-map",
  devServer: {
    contentBase: "./dist",
  },
  entry: "./src/index.js",
  output: {
    filename: "[name].[contenthash].js",
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: "[name].css",
      chunkFilename: "[id].css",
      ignoreOrder: false,
    }),
    new HtmlWebpackPlugin({
      title: "DriverZeng - zls",
      template: "src/assets/index.html",
    }),
  ],
  module: {
    rules: [
      {
        test: /.css$/i,
        use: [
            {
              loader: MiniCssExtractPlugin.loader,
              options: {
                  publicPath: '../',
                  hmr: process.env.NODE_ENV === 'development',
              },
            },
            'css-loader',
        ],
        //use: ["style-loader", "css-loader"],
      },
    ],
  },
};

build一次试试


给CSS文件也加上hash

代码语言:javascript复制
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const path = require("path");

module.exports = {
  mode: "development",
  devtool: "inline-source-map",
  devServer: {
    contentBase: "./dist",
  },
  entry: "./src/index.js",
  output: {
    filename: "[name].[contenthash].js",
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: "[name].[contenthash].css",
      chunkFilename: "[id].[contenthash].css",
      ignoreOrder: false,
    }),
    new HtmlWebpackPlugin({
      title: "DriverZeng - zls",
      template: "src/assets/index.html",
    }),
  ],
  module: {
    rules: [
      {
        test: /.css$/i,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              publicPath: "../",
              hmr: process.env.NODE_ENV === "development",
            },
          },
          "css-loader",
        ],
        //use: ["style-loader", "css-loader"],
      },
    ],
  },
};

再build一次试试

webpack使用多配置文件

我们刚才使用webpack dev server 只能在development的模式下,那么我们代码写完要发布怎么办?

我们需要两个配置文件互相切换

生产我们使用命令 yarn build 开发我们使用命令 yarn start


不同命令使用不同的config

首先创建两个配置文件

webpack.config.js 作为默认的开发环境配置文件 webpack.config.prod.js 作为生产环境的配置文件

webpack.config.js

代码语言:javascript复制
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const path = require("path");

module.exports = {
  mode: "development",
  devtool: "inline-source-map",
  devServer: {
    contentBase: "./dist",
  },
  entry: "./src/index.js",
  output: {
    filename: "[name].[contenthash].js",
  },
  plugins: [
    new HtmlWebpackPlugin({
      title: "DriverZeng - zls",
      template: "src/assets/index.html",
    }),
  ],
  module: {
    rules: [
      {
        test: /.css$/i,
        use: ["style-loader", "css-loader"],
      },
    ],
  },
};

webpack.config.prod.js

代码语言:javascript复制
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const path = require("path");

module.exports = {
  mode: "production",
  devtool: "inline-source-map",
  devServer: {
    contentBase: "./dist",
  },
  entry: "./src/index.js",
  output: {
    filename: "[name].[contenthash].js",
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: "[name].[contenthash].css",
      chunkFilename: "[id].[contenthash].css",
      ignoreOrder: false,
    }),
    new HtmlWebpackPlugin({
      title: "DriverZeng - zls",
      template: "src/assets/index.html",
    }),
  ],
  module: {
    rules: [
      {
        test: /.css$/i,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              publicPath: "../",
            },
          },
          "css-loader",
        ],
      },
    ],
  },
};

配置文件修改完之后,我们通过命令的方式来指定配置文件,修改package.json文件修改里面的命令

代码语言:javascript复制
{
  "name": "webpack-demo-1",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "webpack-dev-server --open",
    "build": "rm -fr dist && npx webpack --config webpack.config.prod.js",
    "test": "echo "Error: no test specified" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "style-loader": "^1.2.1",
    "webpack": "^4.43.0",
    "webpack-cli": "^3.3.11"
  },
  "devDependencies": {
    "css-loader": "^3.5.3",
    "html-webpack-plugin": "^4.3.0",
    "mini-css-extract-plugin": "^0.9.0",
    "webpack-dev-server": "^3.11.0"
  }
}

上面的这种方式,比较low,因为两个配置文件,90%都是一样的,就一行内容不一样,那么我们可以使用一种继承的思想。

首先,创建一个webpack.config.base.js文件,把共同配置都放进去

webpack.config.base.js

代码语言:javascript复制
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const path = require("path");

module.exports = {
  entry: "./src/index.js",
  output: {
    filename: "[name].[contenthash].js",
  },
  plugins: [
    new HtmlWebpackPlugin({
      title: "DriverZeng - zls",
      template: "src/assets/index.html",
    }),
  ],
};

webpack.config.js (开发环境)

代码语言:javascript复制
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const path = require("path");
const base = require("./webpack.config.base.js");

module.exports = {
  ...base,
  mode: "development",
  devtool: "inline-source-map",
  devServer: {
    contentBase: "./dist",
  },
  module: {
    rules: [
      {
        test: /.css$/i,
        use: ["style-loader", "css-loader"],
      },
    ],
  },
};

webpack.config.prod.js (生产环境)

代码语言:javascript复制
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const path = require("path");
const base = require("./webpack.config.base.js");

module.exports = {
  ...base,
  mode: "production",
  plugins: [
    ...base.plugins,
    new MiniCssExtractPlugin({
      filename: "[name].[contenthash].css",
      chunkFilename: "[id].[contenthash].css",
      ignoreOrder: false,
    }),
  ],
  module: {
    rules: [
      {
        test: /.css$/i,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              publicPath: "../",
            },
          },
          "css-loader",
        ],
      },
    ],
  },
};

yarn build的结果,生产环境,有dist目录,并且css是一个文件而且引入到index.html了

yarn start的结果,开发环境,没有dist目录,直接打开浏览器

并且css是一个style标签

webpack引入scss

我们去百度搜索,会让安装sass-loader和node-sass

但是node-sass已经过时了,我们现在使用dart-sass

代码语言:javascript复制
MacBook-pro:webpack-demo-1 driverzeng$ yarn add sass-loader dart-sass --dev

创建scss并引入

代码语言:javascript复制
body {
  background: black;
}

修改webpack配置文件

webpack.config.base.js (共用属性)

代码语言:javascript复制
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const path = require("path");

module.exports = {
  entry: "./src/index.js",
  output: {
    filename: "[name].[contenthash].js",
  },
  plugins: [
    new HtmlWebpackPlugin({
      title: "DriverZeng - zls",
      template: "src/assets/index.html",
    }),
  ],
  module: {
    rules: [
      {
        test: /.s[ac]ss$/i,
        use: [
          "style-loader",
          "css-loader",
          {
            loader: "sass-loader",
            options: {
              implementation: require("dart-sass"),
            },
          },
        ],
      },
    ],
  },
};

webpack.config.js (开发环境)

代码语言:javascript复制
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const path = require("path");
const base = require("./webpack.config.base.js");

module.exports = {
  ...base,
  mode: "development",
  devtool: "inline-source-map",
  devServer: {
    contentBase: "./dist",
  },
  module: {
    rules: [
      ...base.module.rules,
      {
        test: /.css$/i,
        use: ["style-loader", "css-loader"],
      },
    ],
  },
};

webpack.config.prod.js (生产环境)

代码语言:javascript复制
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const path = require("path");
const base = require("./webpack.config.base.js");

module.exports = {
  ...base,
  mode: "production",
  plugins: [
    ...base.plugins,
    new MiniCssExtractPlugin({
      filename: "[name].[contenthash].css",
      chunkFilename: "[id].[contenthash].css",
      ignoreOrder: false,
    }),
  ],
  module: {
    rules: [
      ...base.module.rules,
      {
        test: /.css$/i,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              publicPath: "../",
            },
          },
          "css-loader",
        ],
      },
    ],
  },
};

webpack引入LESS和Stylus

经验:SASS、LESS、Stylus完全没有区别


修改文件后缀

使用JS引入less

代码语言:javascript复制
import "./y.less"

安装less-loader

代码语言:javascript复制
MacBook-pro:webpack-demo-1 driverzeng$ yarn add  less less-loader@5 --dev

修改配置文件

webpack.config.base.js

代码语言:javascript复制
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const path = require("path");

module.exports = {
  entry: "./src/index.js",
  output: {
    filename: "[name].[contenthash].js",
  },
  plugins: [
    new HtmlWebpackPlugin({
      title: "DriverZeng - zls",
      template: "src/assets/index.html",
    }),
  ],
  module: {
    rules: [
      {
        test: /.less$/,
        loader: ["style-loader", "css-loader", "less-loader"],
      },
      {
        test: /.s[ac]ss$/i,
        use: [
          "style-loader",
          "css-loader",
          {
            loader: "sass-loader",
            options: {
              implementation: require("dart-sass"),
            },
          },
        ],
      },
    ],
  },
};

另外两个配置文件,内容不变


创建Stylus文件

VScode需要在编辑器里安装一个支持styl文件的扩展

然后创建一个styl的文件

代码语言:javascript复制
body{
    background: gray;
}

mdzz 就跟css一样,当然还有其他的语法

然后js引入

代码语言:javascript复制
import "./x.css";
import "./y.less";
import "./z.styl";

安装stylus插件

代码语言:javascript复制
MacBook-pro:webpack-demo-1 driverzeng$ yarn add stylus-loader stylus --dev

修改webpack配置文件

webpack.config.base.js

代码语言:javascript复制
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const path = require("path");

module.exports = {
  entry: "./src/index.js",
  output: {
    filename: "[name].[contenthash].js",
  },
  plugins: [
    new HtmlWebpackPlugin({
      title: "DriverZeng - zls",
      template: "src/assets/index.html",
    }),
  ],
  module: {
    rules: [
      {
        test: /.styl$/,
        loader: ["style-loader", "css-loader", "stylus-loader"],
      },
      {
        test: /.less$/,
        loader: ["style-loader", "css-loader", "less-loader"],
      },
      {
        test: /.s[ac]ss$/i,
        use: [
          "style-loader",
          "css-loader",
          {
            loader: "sass-loader",
            options: {
              implementation: require("dart-sass"),
            },
          },
        ],
      },
    ],
  },
};

webpack引入图片

首先,我们使用js操作html引入一个图片

下载一个图片,放入assets文件夹中,然后使用js调用,插入html

代码语言:javascript复制
const div = document.getElementById("zls1");

div.innerHTML = `
    <img src="./assets/1.jpeg">
`;

直接build会发现,我靠,根本找不到图片,因为这个图片指定的路径是assets目录,但是我们build完了之后,你的代码目录是dist目录啊...所以我们需要使用webpack引入图片


安装file-loader

代码语言:javascript复制
MacBook-pro:webpack-demo-1 driverzeng$ yarn add  file-loader@4  --dev

修改webpack配置文件

webpack.config.base.js

代码语言:javascript复制
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const path = require("path");

module.exports = {
  entry: "./src/index.js",
  output: {
    filename: "[name].[contenthash].js",
  },
  plugins: [
    new HtmlWebpackPlugin({
      title: "DriverZeng - zls",
      template: "src/assets/index.html",
    }),
  ],
  module: {
    rules: [
      {
        test: /.(png|svg|jpg|jpeg|gif)$/,
        use: ["file-loader"],
      },
      {
        test: /.styl$/,
        loader: ["style-loader", "css-loader", "stylus-loader"],
      },
      {
        test: /.less$/,
        loader: ["style-loader", "css-loader", "less-loader"],
      },
      {
        test: /.s[ac]ss$/i,
        use: [
          "style-loader",
          "css-loader",
          {
            loader: "sass-loader",
            options: {
              implementation: require("dart-sass"),
            },
          },
        ],
      },
    ],
  },
};

使用js导入图片

代码语言:javascript复制
import "./x.css";
import "./y.less";
import "./z.styl";
import jpg from "./assets/1.jpeg";
const div = document.getElementById("zls1");

div.innerHTML = `
    <img src="${jpg}">
`;

导入图片后,使用build或者start看看效果

0 人点赞