webpack

2,505 阅读4分钟

webpack 基于Node.js静态资源的模块打包器

当打包时 会从一个七点开始查找各模块的依赖关系,并且按照依赖关系将文件打包成一个或多个包

使用webpack打包的优点

  • 模块化 通过模块化管理这些依赖
  • 自动编译less sass
  • 可以把基于js的扩展语言编译成js
  • 开发环境配置代理解决开发环境跨域

安装 全局安装

npm i webpack-cil -g
npm i webpack -g

手动配置 webpack

  • 新建文件夹 webpack
  • 在webpack下新建文件夹 app public
  • 在 app 下 新建 Greeter.js main.js config.json
  • 在public目录下新建index.html
  • 写入代码
Greeter.js


let config = require('./config.json');
module.exports = function(){
    var greet = document.createElement('div');
    greet.textContent = config.greeterText;
    return greet;
}

config.json


{"greetText":"this is json"}
main.js

const greeter = require('./Greeter.js');
document.querySelector('#root').appendChild(greeter());
console.log(1);
/pubilc/index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="root"></div>
<p class="paragraph">12333</p>
<div>xxxxxx</div>

<script src="bundle.js"></script>
</body>
</html>
  • 在webpack目录下打开命令行 输入打包命令
webpack-cli --entry./app/main.js --output ./public/bundle.js
  • 打开HTML页面

配置 npm scripts 为了减少配置参数的量

  • 先生成一个package.json文件
  • 里面有一个 script对象 在这个对象中每一个属性都可以通过 npm run 执行的命令
{
    "name":"wbp",
    "version":"1.0.0",
    "description":"",
    "main":"index.js",
    "scripts":{
        "test": "echo \"Error: no test specified\" && exit 1",
        "cmdBuild": "webpack-cli --entry ./app/main.js --output ./public/bundle.js"
    },
     "keywords": [],
     "author": "",
     "license": "ISC"
}
//在 cmd 中执行 npm run cmdBuild 就相当于在执行 webpack-cli --entry ./app/main.js --output ./public/bundle.js 命令;

webpack配置文件

在项目根目录下创建一个webpack.config.js webpack打包时会自动加载文件名为webpackconfig.js的文件

本地安装 webpack-cli webpack

npm i webpack-cli webpack --save-dev

配置 入口 出口

  • entry(入口) 打包的起点 从这个文件开始查找依赖关系
  • output(出口) 打包后的文件输出的目录和文件名
module.exports = {
  entry: __dirname + '/app/main.js',
  output: {
    path: __dirname + '/public', // 打包后文件存放的地方
    filename: 'bundle.js' //打包后的文件名
  }

配置 source-map

js代码编译后 可读性差 不利于调试 而浏览器有一种scource-map机制 可以通过这个机制 将js文件虚拟还原成打包之前的样子 这样方便调试 **webpack 在打包结束后 可以自动生成scource map **

module.exports = {
  devtool: "eval-source-map", // 生成source-map
  entry: __dirname + '/app/main.js',
  output: {
    path: __dirname + '/public', // 打包后文件存放的地方
    filename: 'bundle-[hash:5].js'
  }
};

配置打包的npm script 在webpack.json中配置build命令

{
  "name": "wbp",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack",
    "cmdBuild": "webpack-cli --entry ./app/main.js --output ./public/bundle.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
//在命令行中执行 npm run build 即可打包

配置dev-server

一般在开发过程中 我们需要让webpack给我们启动一个本地服务器

  • 这样可以让浏览器监听医德代码的修改 并自动刷显示修改后的结果
  • 提供ajax接口的代理 解决开发环境的跨域问题

安装

npm i webpack-dev-server --save-dev

在webpack中添加配置项

 devServer: {
    contentBase: './public', // 本地服务器所加载的页面所在的目录
    historyApiFallback: true, // 单页面应用路由切换时不跳转
    inline: true, // 实时刷新
    port: 8080, //启动时的端口号
    proxy: { //代理配置
      '/api': { // 如果接口中带有 API 标志,那么就需要开始代理
        target: 'http://localhost:8001',
        changeOrigin: true,  // target 是域名的话,需要这个参数,
        secure: false  // 设置支持 https 协议的代理,不检查安全与否
      }
    }

启动 dev-server

{
  "name": "wbp",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack",
    "cmdBuild": "webpack-cli --entry ./app/main.js --output ./public/bundle.js",
    "dev": "webpack-dev-server --open"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "webpack-dev-server": "^3.7.2"
  }
}

配置loaders 解决webpack只能处理js文件

loader 需要单独安装并且需要在webpack.config.js中的modules关键字下进行配置

 module: {
    rules: [
      {
        test: /(\.jsx|\.js)$/, //一个用以配置loaders所处理文件得扩展名的正则表达式(必须)
        use: { //loader 的名称(必须)
          loader: "babel-loader",
          options: {
            presets: ['env', 'react']
          }
        },
        include/exclude: /node_modules/, //手动添加必须处理的文件(夹)或屏蔽不需要的文件(夹)(可选)
        query:为loaders提供额外的设置选项(可选)
      }
    ]
  }

配置babel 编译js的平台 在这里 可以使用最新的js代码 不管当前使用的浏览器是否完全支持 可以使用基于js的扩展的语言 如 jsx

安装

  • babel-core babel 的核心
  • babel-loader babel的 loader (安装7.x.x 版本,如7.1.5)
  • babel-preset-env 把 ES5/6/7 转成当前能使用的版本
  • babel-preset-react 解析 React 的 JSX 语法
npm i babel-core babel-loader@7.1.5 babel-preset-env babel-preset-react --save-dev

使用

  module: {
    rules: [
      {
        test: /(\.jsx|\.js)$/,
        use: {
          loader: "babel-loader",
          options: {
            presets: ['env', 'react']
          }
        },
        exclude: /node_modules/
      }
    ]
  }

配置CSS loader less-loader 使css 可以像js那样导进来

安装 css-loader style-loader

  • 安装 css-loader 可以使用 @import 或者 url 等方法导入其他资源
  • style-loader 将所有计算后的样式加入页面中
npm i style-loader caaa-loader less less-loader--save-dev

###在webpack中配置loader

 module: {
    rules: [
      {
        test: /(\.jsx|\.js)$/,
        use: {
          loader: "babel-loader",
          options: {
            presets: ['env', 'react']
          }
        },
        exclude: /node_modules/
      },
      {
        test: /\.css$/,
        use: [
          {
            loader: 'style-loader'
          },
          {
            loader: 'css-loader'
          }
        ]
      },
      {
        test: /\.less$/,
        use: ['style-loader', 'css-loader', 'less-loader']  
      },
      {
          test:/\.(png/jpg/gif)$/,
          use:{
              loader:'url-loader'
          }
      }
    ]
  }

配置 url-loader 配置后 可以导入图片

安装

npm i url-loader --save-dev

插件 (Plugins) 用来拓展webpack功能 会在真个构建过程中生效 执行相关的任务

插件的使用

  • 安装 html-webpack-plugin
npm i html-webpack-plugin --save-dev

  • 引入插件
let HTMLWebpackPlugin = require('html-webpack-plugin ')
  • 在 webpack 中增加一个 plugins 字段,它的值是一个数组,使用插件就是创建一个插件的实例,然后作为数组项放到 plugins 中;
 plugins: [
    new HtmlWebpackPlugin({
      template: __dirname + '/public/index.html' // 指定一个模板,webpack 将会按照这个模板创建 html
    })
  ]
  • 执行后 在 build 目录下有一个 index.html 和 bundle.js;同时 index.html 已经自动引入了 bundle.js