webpack基础教程(简单使用)

目录

 

一 、webpack是什么?

二、 安装webpack

 三、webpack基本打包命令

1. webpack起步

2. webpack打包js

3. webpack编译es6 

4. webpack提取公共代码(多页面应用) 

 5. webpack单页面解决方案–代码分割和懒加载

6. webpack处理CSS

 7. webpack处理SCSS


一 、webpack是什么?

Webpack 是一个前端资源加载/打包工具。它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源。(本文以webpack4为准)

二、 安装webpack

首先确保本地环境支持node.js,再使用npm安装webpack,如果觉得npm安装速度慢,可使用淘宝镜像及其命令cnpm

  • 全局安装webpack命令行如下
  • npm install webpack -g
    
  • 项目安装webpack命令行如下
  • npm install webpack --save-dev

 三、webpack基本打包命令

1. webpack起步

  • 新建一个项目目录webpack,在目录下添加main.js文件,代码如下:
document.write("哈哈哈哈哈哈哈哈哈哈");
  • 在webpack目录下添加index.html文件,代码如下:
<html>
    <head>
        <meta charset="utf-8">
    </head>
    <body>
        <script type="text/javascript" src="bundle.js" charset="utf-8"></script>
    </body>
</html>
  • 接下来使用webpack命令来打包,命令如下
webpack main.js bundle.js
  • 执行以上命令会编译main.js文件并生成bundle.js文件,打开index.html,会显示“哈哈哈哈哈哈哈哈哈哈”

2. webpack打包js

  • 新建项目demo01,在demo01底下新建文件夹vendor,在vendor文件夹底下新建sum.js文件,使用ES6模块导出,代码如下
export default function(a, b) {
  return a + b;
}

  • 在demo01底下新建app.js文件,作为项目的入口文件,代码如下
/**
 * webpack支持ES6、CommonJs和AMD规范
 */

// ES6
import sum from "./vendor/sum";
console.log("sum(1, 2) = ", sum(1, 2));
  • 在demo01文件夹底下新建webpack.config.js文件,进行打包配置,代码如下:
/**
 * 必须使用CommonJs规范
 * 更多高级用法:https://www.webpackjs.com/concepts/output/
 */

const path = require("path");

module.exports = {
  entry: {
    app: "./app.js"
  },
  output: {
    publicPath: __dirname + "/dist/", // js引用路径或者CDN地址
    path: path.resolve(__dirname, "dist"), // 打包文件的输出目录
    filename: "bundle.js"
  }
};

  • 怎么运行呢,首先,得安装webpack,具体安装命令见上文,再使用npm init -y生成package.json文件,配置script,代码如下,再使用npm run build 进行打包。最后项目底下会生成一个文件夹dist,文件夹里有打包后的文件bundle.js,至此打包js完成。
{
  "name": "meetwebpack",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "dependencies": {
    "webpack-cli": "^4.1.0"
  },
  "devDependencies": {},
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack"
  },
  "author": "",
  "license": "ISC"
}

  • 打包后的目录结构

3. webpack编译es6 

  • 说到编译ES6,就不得不提到和babel相关的技术生态,具体情况如下:
    babel-loader: 负责 es6 语法转化
    babel-preset-env: 包含 es6、7 等版本的语法转化规则
    babel-polyfill: es6 内置方法和函数转化垫片
    babel-plugin-transform-runtime: 避免 polyfill 污染全局变量

    这里需要注意的是:babel-loader和babel-polyfill,前者负责语法转化,比如:箭头函数啥的,后者负责内置方法和函数,比如 new Set()
  • 所以webpack要编译ES6,第一步得安装相关的库,这次,package.json文件配置如下:(记得npm install)
{
  "devDependencies": {
    "babel-core": "^6.26.3",
    "babel-loader": "^7.1.5",
    "babel-plugin-transform-runtime": "^6.23.0",
    "babel-preset-env": "^1.7.0",
    "webpack": "^4.15.1"
  },
  "dependencies": {
    "babel-polyfill": "^6.26.0",
    "babel-runtime": "^6.26.0"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack"
  }
}
  • 在webpack中使用babel,babel的相关配置,单独写在.babelrc文件中,相关配置如下:
{
  "presets": [
    [
      "env",
      {
        "targets": {
          "browsers": ["last 2 versions"]
        }
      }
    ]
  ],
  "plugins": ["transform-runtime"]
}

  • 在webpack配置文件中,关于babel的调用需要写在module模块中。对于相关的匹配规则,除了匹配js结尾的文件,还应该去除node_module文件夹下的第三方库。

 /* 相关步骤:
 *    1 安装相关库
 *    2 在webpack中使用babel,babel的相关配置,单独写在.babelrc中
 *    3 在webpack配置文件中,关于Babel的调用需要写在module模块中
 *    4 babel-polyfill它需要在我们项目的入口文件中被引入(这里使用这种),或者在webpack.config.js中配置。
 */
module.exports = {
  entry: {
    app: "./app.js"
  },
  output: {
    filename: "bundle.js"
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        // 这里应该除去node_modules文件夹下的第三方库文件
        exclude: /(node_modules)/,
        use: {
          loader: "babel-loader" // 转化需要的loader
          // options选项配置在: .babelrc
          // options: {
          //   ...
          // }
        }
      }
    ]
  }
};

  • 项目入口文件app.js,在这里我们要引入babel-polyfill,具体代码如下:
import "babel-polyfill";
let func = () => {};
const NUM = 45;
let arr = [1, 2, 4];
let arrB = arr.map(item => item * 2);

console.log(arrB.includes(8));
console.log("new Set(arrB) is ", new Set(arrB));
  • 安装完webpack之后,使用npm run build进行打包,会生成dist文件夹,及bundle.js,到此es编译打包结束。可以在html文件中引用打包后的文件,打开html文件即可查看效果。打包后的目录结构如下图所示:
    在这里插入图片描述
  •  

4. webpack提取公共代码(多页面应用) 

  • 首先,先在src文件夹下创建 pageA.js 和 pageB.js分别作为两个入口文件。同时,这两个入口文件同时引用subPageA.js,subPageB.js,而subPageA.js,subPageB.js又同时引用module.js文件。
    项目基本结构如下:
    在这里插入图片描述
  • module.js代码如下:
export default "module";
  • subPageA.js:导入公共模块module
import "./module";
export default "subPageA";
  • subPageB.js:导入公共模块module
import "./module";
export default "subPageB";
  • 最后封装入口文件,pageA.js
import "./subPageA";
import "./subPageB";

import * as _ from "lodash";
console.log("At page 'B' :", _);

export default "pageA";

pageB.js:

import "./subPageA";
import "./subPageB";

import * as _ from "lodash";
console.log("At page 'A' :", _);

export default "pageB";

  • 然后编写package.js配置文件,代码如下:
{
  "devDependencies": {
    "webpack": "^4.15.1"
  },
  "dependencies": {
    "lodash": "^4.17.10"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack"
  }
}

  • 最后编写webpack配置文件,进行打包配置,具体代码如下:
const webpack = require("webpack");
const path = require("path");

module.exports = {
  // 多页面应用
  entry: {
    pageA: "./src/pageA.js",
    pageB: "./src/pageB.js"
  },
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "[name].bundle.js",
    chunkFilename: "[name].chunk.js"
  },
  // 着重看这个配置,将需要打包的代码放在 cacheGroups属性中
  optimization: {
    splitChunks: {
      cacheGroups: {
        // 注意: priority属性
        // 其次: 打包业务中公共代码,每个键值对就是被打包的一部分,
        //       针对第三方库通过设置priority来让其先被打包提取,最后再提取剩余代码
        common: {
          name: "common",
          chunks: "all",
          minSize: 1,
          priority: 0
        },
        // 首先: 打包node_modules中的文件
        vendor: {
          name: "vendor",
          test: /[\\/]node_modules[\\/]/,
          chunks: "all",
          priority: 10
          // enforce: true
        }
      }
    }
  }
};

  • npm install 之后,使用npm run build 进行打包,打包后的项目目录结构如下图所示:
    在这里插入图片描述

 5. webpack单页面解决方案–代码分割和懒加载

  • 针对单页应用提取公共代码需要通过代码分割和懒加载
  • 代码分割和懒加载是通过代码写法来实现(见下文page.js代码),并不是通过webpack配置来实现
  • 此demo的package.json代码如下:
{
  "devDependencies": {
    "webpack": "^4.15.1"
  },
  "dependencies": {
    "lodash": "^4.17.10"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack"
  }
}

  • 公共模块module.js:
export default "module";

  • subPageA.js:
import "./module";
console.log("I'm subPageA");
export default "subPageA";
  • subPageB.js:
import "./module";
console.log("I'm subPageB");
export default "subPageB";

  • page.js:重点代码在这里
/**
 * requir.ensure(): 只是加载并不执行
 * import(): 加载并且自动执行
 */

import(/* webpackChunkName: 'subPageA'*/ "./subPageA").then(function(subPageA) {
  console.log(subPageA);
});

import(/* webpackChunkName: 'subPageB'*/ "./subPageB").then(function(subPageB) {
  console.log(subPageB);
});

import(/* webpackChunkName: 'lodash'*/ "lodash").then(function(_) {
  console.log(_.join(["1", "2"]));
});

export default "page";
  • webpack配置文件如下:
const webpack = require("webpack");
const path = require("path");

module.exports = {
  entry: {
    page: "./src/page.js" //
  },
  output: {
    publicPath: __dirname + "/dist/", 
    path: path.resolve(__dirname, "dist"),
    filename: "[name].bundle.js",
    chunkFilename: "[name].chunk.js"
  }
};

  • 使用npm run build命令进行打包,打包后的项目目录如下:

在这里插入图片描述

6. webpack处理CSS

在这里插入图片描述

  • 项目依赖如下:
{
  "devDependencies": {
    "css-loader": "^1.0.0",
    "file-loader": "^1.1.11",
    "style-loader": "^0.21.0"
  },
   
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack"
  }
}

  • base.css:
*,
body {
  margin: 0;
  padding: 0;
}
html {
  background: red;
}

  • app.js:
let clicked = false;
window.addEventListener("click", function() {
  if (!clicked) {
    // 加载css样式文件
    import("./css/base.css");
  }
});

// style-loader/useable:
// 可以直接使用use()或者unuse()方法来加载/卸载CSS样式
//
// import base from "./css/base.css";
// var flag = false;
// setInterval(function() {
//   if (flag) {
//     base.unuse();
//   } else {
//     base.use();
//   }
//   flag = !flag;
// }, 500);

  • css.transform.js:
// transform 选项是在import css样式后执行的
module.exports = function(css) {
  console.log(css);
  return window.innerWidth < 1000 ? css.replace("red", "green") : css;
};

  • webpack配置文件如下
const path = require("path");

module.exports = {
  entry: {
    app: "./src/app.js"
  },
  output: {
    publicPath: __dirname + "/dist/",
    path: path.resolve(__dirname, "dist"),
    filename: "[name].bundle.js"
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        // css处理为style标签
        use: [
          {
            loader: "style-loader",
            options: {
              singleton: true,
              transform: "./css.transform.js"
            }
          },
          {
            loader: "css-loader",
            options: {
              minimize: true
            }
          }
        ]
        // css处理为link标签
        // use: [
        //   {
        //     loader: "style-loader/url"
        //   },
        //   {
        //     loader: "file-loader"
        //   }
        // ]
        // css卸载和加载样式(use与unuse方法)
        // use: [
        //   {
        //     loader: "style-loader/useable"
        //   },
        //   {
        //     loader: "css-loader"
        //   }
        // ]
      }
    ]
  }
};

  • 使用npm run build命令打包,项目打包后的目录如下:
  • 在这里插入图片描述

 7. webpack处理SCSS

在这里插入图片描述

  • 项目所需依赖如下:
{
  "devDependencies": {
    "css-loader": "^1.0.0",
    "extract-text-webpack-plugin": "^4.0.0-beta.0",
    "node-sass": "^4.9.2",
    "sass-loader": "^7.0.3",
    "style-loader": "^0.21.0",
    "webpack": "^4.16.0"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack"
  }
}
  • base.scss:
$bgColor: red !default;

*,
body {
  margin: 0;
  padding: 0;
}

html {
  background-color: $bgColor;
}

  • 在app.js中导入scss文件:
import "./scss/base.scss";

  • 配置webpack:注意loader顺序,不能颠倒,只有通过css-loader处理css之后才能通过style-loader,指定多个loader时的顺序是固定的,而调用loader的顺序是从前往后解析的
const path = require("path");

module.exports = {
  entry: {
    app: "./src/app.js"
  },
  output: {
    publicPath: __dirname + "/dist/",
    path: path.resolve(__dirname, "dist"),
    filename: "[name].bundle.js"
  },
  module: {
    rules: [
      {
        test: /\.scss$/,
        // 注意 loader 顺序,不能颠倒
        use: [
          {
            loader: "style-loader" // 将 JS 字符串生成为 style 节点
          },
          {
            loader: "css-loader" // 将 CSS 转化成 CommonJS 模块
          },
          {
            loader: "sass-loader" // 将 Sass 编译成 CSS
          }
        ]
      }
    ]
  }
};

  • 使用npm run build打包,打包后的文件结构如下:
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值