webpack安装

安装


webpack 是一个使用Node.js实现的一个模块化代码打包工具。所以,需要先安装webpack,安装之前需要搭建好Node.js环境

npm install -D webpack webpack-cli

注:不推荐全局安装

webpack-cli:提供webpack命令、工具

使用


// 初始化项目 生成package.json文件
npm init -y

./node_modules/.bin/webpack
// 查看版本
./node_modules/.bin/webpack -v

也可以编辑package.json的scripts来简化输入

// package.json
{
  ...
  "scripts": {
    "start": "webpack" // scripts中可以定位到./node_modules/.bin 目录下
  }
}

scripts 中使用test、start、restart、stop命令时,可以在调用的时候省略run,直接npm start

或者使用更方便的方式,npx可以定位到./node_modules/.bin 目录下

 npx webpack
// npm5.2+增加,如果没有,可以使用npm i -g npx 来安装

打包模块


入口文件

入口文件就是我们项目中加载的第一个文件,比如main.js文件,其他文件都是通过import等方式引入的,webpack会从我们指定的入口文件开始分析所有需要依赖的文件,然后打包成一个完整的文件。

打包命令

webpack ./js/index.js

上面的命令会使用webpack默认的一些配置对模块文件进行打包,并把打包后的文件输出到默认创建的./dist目录下,打包后的文件名默认为main.js。
模块文件打包以后,就可以在不支持es6模块语法的浏览器环境下引入使用了。

打包文件分析

  • 把分散的模块文件打包到一个文件中,不需要外部引入了
  • 内置了一个小型模块加载器(类似requireJS),实现了打包后的代码隔离与引用
    以上就是webpack最基础的使用基本原理。

打包配置


虽然,可以直接通过命令来打包,但还是推荐创建一个webpack.config.js的配置文件来实现。webpack命令在运行的时候,默认会读取运行命令所在的目录的webpack.config.js文件,通常我们会在项目的根目录下运行命令和创建配置文件。也可以使用--config选项来指定配置文件路径:

webpack --config ./configs/webpack.config.js

配置文件
导出的就是一个对象,这个对象就是webpack命令执行过程中使用到的配置

module.exports = {
  ... // 配置项
}

核心配置


编译模式( mode)

module.exports = {
  mode: 'development' // 可以配置为production | development | none
}

编译入口文件(entry)

指定打包入口文件,有三种不同的形式:string | object | array

// 一对一:一个入口文件、一个打包文件
module.exports = {
  entry: './src/index.js'
}

// 多对一:多个入口文件,一个打包文件
module.exports = {
  entry: [
    './src/index.js',
    './src/main.js'
  ]
}
// 多对多:多个入口文件,多个打包文件
module.exports = {
  entry: {
    main: './src/main.js',
    index: './src/index.js'
  }
}

编译出口配置(output)

打包后的文件位置

import path = require('path');
module.exports = {
  output: {
    path: path_resolve(__dirname, "dist"),
    filename: 'bundle.js',
   // filename: '[name].js' // 变量占位符,用于多出口
  }
}
  • 可以指定一个固定的文件名称,如果是多入口多出口(entry为对象),则不能使用单文件出口
  • 通过webpack内置的变量占位符:[name]

参考官网配置

深入


执行简要流程

entry -> loaders -> plugins -> output

  • loaders:核心内容之一,非js类型的模块处理,不同类型的模块的解析就是依赖不同的loader来实现的。
  • plugins:一组webpack的插件,主要扩展webpack本身的一些功能,它们会运行在各种模块解析完成以后的打包编译阶段,比如对解析后的模块文件进行压缩等

Loaders

官方文档

raw-loader

// 安装
 npm install raw-loader --save-dev
module.exports = {
  ...
  // 模块配置
  // loader配置
  module: {
    // 非js模块的加载规则和需要调用的loader处理器
    rules: [
      // 每一个对象就是一个处理规则
      {
        test: /\.txt$/, // 被加载的模块特征:正则,一般通过被加载文件的后缀来进行判断
        use: 'raw-loader' // 如果加载的模块文件满足上面的特征,则调用use中设定的loader进行处理
      }
    ]
  }
}

当webpack碰到不识别的模块的时候,webpack会在配置的module中进行该文件规则的查找

  • rules就是我们为不同类型的文件定义的解析规则对应的loader,它是一个数组
  • 每一种类型规则通过test选项来定义,通常我们会通过正则的方式来匹配文件后缀类型
  • use针对匹配到文件类型,调用对应的loader进行处理

markdown-loader

// 安装
npm i -D markdown-loader html-loader
module.exports = {
   ...
  module: {
    rules: [
      {
        test: /\.md$/,
        use: [
          // 这里处理loader的顺序是由下至上
          {
            loader: 'html-loader' // 后处理
          },
          {
            loader: 'markdown-loader' // 先处理,会处理成html格式
          }
        ]
      }
    ]
  }
}

file-loader

把识别出的资源模块,移动到指定的输出目录,并且返回这个资源在输出目录的地址(字符串)

// 安装
npm i --save-dev file-loader
rules: [
  ...,
  {
    test: /\.(png|jpe?g|gif)$/,
    use: {
      loader: 'file-loader',
      options: {
        // placeholder 占位符[name] 源资源模块的名称 [ext] 源资源模块的后缀
        name: "[name]_[hash].[ext]",
        // 打包后的存放位置
        outputPath: "./images",
        // 打包后文件的 url,虚拟目录
        publicPath: "./public"
      }
    }
  }
]

url-loader

可以处理file-loader所有的事情,但是遇到图片格式的模块,可以选择性的把图片转成base64格式的字符串,并打包到js中,对小体积的图片比较合适,大图片不合适。

npm install --save-dev url-loader
rules:[
  {
    test: /\.(png|jpe?g|gif)$/,
    use: {
      loader: 'url-loader',
      options: {
        name: "[name]_[hash].[ext]",
        outputPath: "./images",
        publicPath: "./images",
        limit: 100 // 小于100字节转成base64格式
      }
    }
  }
]

css-loader

// 文件引用
import css from './css/common.css';
let styleElement = document.createElement('style');
styleElement.innerHTML = css[0][1];
document.head.appendChild(styleElement);

style-loader

// 文件直接引用
import './css/common.css';

//  module配置
rules: [
  {
    test: /\.css$/,
    use: ['style-loader', 'css-loader']
  }
]

同一个任务的loader可以同时挂载多个,处理顺序为:从右到左,也就是先通过css-loader处理,然后反悔上理后的css字符串交给style-loader进行处理。

// 多个
rules: [
  {
    test: /\.css$/,
    use: [
      {
          loader: 'style-loader',
          options: {}
        },
         'css-loader'
    ]
  }
]

官方文档

Plugins


扩展webpack本身的一些功能,它们会运行在各种模块解析完成以后的打包编译阶段,比如对解析后的模块文件进行压缩等。打包之后,保存之前。

HtmlWebpackPlugin

打包结束后,自动生成一个html文件,并把打包生成的js模块引入到该html中

npm install --save-dev html-webpack-plugin
const HtmlWebpackPlugin = require('html-webpack-plugin');
  
module.exports = {
  ...,
  plugins: [
    new HtmlWebpackPlugin({
      title: 'my App', // 用来生成页面的title元素
      filename: 'app.html', // 输出的HTML文件名,默认是index.html,也可以配置子目录
      template: './src/html/index.html' // 模板文件路径,支持加载器loader
    })
  ]
}

在html模版中,可以通过<%=htmlWebpackPlugin.options.xxx%>的方式获取配置的值

clean-webpack-plugin

删除(清理)构建目录

npm install --save-dev clean-webpack-plugin
const { CleanWebpackPlugin }  = require('clean-webpack-plugin');

module.exports = {
  ...,
  plugins: [
    ...,
    new CleanWebpackPlugin(),
    ...
  ]
}

mini-css-extract-plugin

提取css到一个单独的文件中

npm install --save-dev mini-css-extract-plugin
const MiniCssExtractPlugin = rquire('mini-css-extract-plugin');

module.exports = {
  ...,
  module: {
    rules: [
      {
        test: /\.s[ac]ss$/,
        use: [
          {
              loader: MinCssExtractPlugin.loader
          },
          'css-loader',
          'sass-loader'
        ]
      }
    ]
  },
  plugins: [
     new MinCssExtractPlugin(
      {
        filename: '[name].css'
      }
    )
  ]
}

sourceMap



我们实际运行在浏览器的代码是通过webpack打包合并甚至压缩混淆过的代码,所以生成的代码并不利于我们的调试和错误定位,我们可以通过sourceMap来解决这个问题,sourceMap本质是一个记录了编译后代码与源代码的映射关系的文件,我们可以通过webpack的devtool选项来开启sourceMap

module.exports = {
  mode: 'production',
  devtool: 'source-map'
}

首先,编译后会为每一个编译文件生成一个对应的 .map 文件,同时在编译文件中添加一段对应的map文件引入代码

//# sourceMappingURL = xx.js.map

//*# sourceMappingURL = xx.css.map*/

同时,浏览器能够识别sourceMap文件,在sources面板中显示根据编译文件与对应的map文件定位到源文件中,有利于我们的调试和错误定位。

WebpackDevServer

安装webpackDevServer可以避免每次的代码修改都需要重新编译打包,刷新浏览器。

npm install --save-dev webpack-dev-server

启动命令

npx webpack-dev-server

或者package.json中添加scripts

...,
  "scripts": {
    "server": "webpack-dev-server"
  }
}

修改webpack.config.js

module.exports = {
  ...,
  devServer: {
    static: {
      directory: path.join(__dirname, 'public'),
    },
    compress: true,
    port: 8081 // 端口    
  }
}

Proxy


处理后端请求时会出现跨域的问题,webpackDevServer内置了一个代理服务,通过内置代理就可以把我们的跨域请求转发目标服务器上(webpackDevServer内置的代理发送的请求属于后端 - node,不受同源策略限制),具体如下:
使用node模拟服务端接口

// 安装
npm i koa koa-router
npm i -g supervisor

// 启用
supervisor app
const Koa = require('koa');
const KoaRouter = require('koa-router');

const app = new Koa();
const router = new KoaRouter();

router.get('/getdata',async ctx => {
    ctx.body = {
      userName: 'zMouse',
      gender: 'male'
    }
})

app.use(router.routes());
app.listen(7777);

webpack.config.js 配置

devServer: {
        port: 8081,
        // // 我们的每次请求都会被devServer拦截,然后如同webpack中的loader,如果请求的url满足proxy中的某个规则的话,则把这个请求转发到另外一个服务器上
        proxy: {
            '/api': {
                // 把原始请求中的域转成target的域
                target: 'http://localhost:7777',
                // 把请求路径中的 /api 去掉
                pathRewrite: {
                    '^/api': ''
                }
            }
        }
    }

页面调用

async function getData() {
    let res = await fetch('/api/getdata');
    console.log(res);
    let data = await res.text();
    console.log(data)
}

getData();

你可能感兴趣的:(webpack安装)