meface/docs/article/web/tool/webpackTool.md

11 KiB
Raw Blame History

title: 'Webpack' date: 2020-10-10 author: 'ac' tags: - Webpack categories: - Web

1.前端工程化

实际的前端开发:

  • 模块化js模块化、css模块化、资源的模块化
  • 组件化UI结构、样式、行为的复用
  • 规范化(目录的结构划分、编码规范化、接口规范化)
  • 自动化(自动构建、部署、测试)

前端工程化指的是:在企业级的前端项目开发中,把前端开发所需的工具技术流程经验等进行规范化、

标准化。

好处:前端开发自成体系,有一套标准的开发方案和流程。

工程化解决方案:

2. Webpack的基本使用

webpack 是前端项目工程化的具体解决方案。

Webpack是前端资源加载/打包工具,它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源。 Webpack 可以将多种静态资源 js、css、less 转换成一个静态文件,减少了页面的请求。

主要功能:它提供了友好的前端模块化开发支持,以及代码压缩混淆、处理浏览器端 JavaScript 的兼容性性能优化等强大的功能。

Webpack 全局安装

npm install webpack -g

到了 webpack4命令行相关的内容都移到 webpack-cli所以还需要安装 webpack-cli

npm install webpack-cli -g

Webpack 根据模块的依赖关系进行静态分析,这些文件(模块)会被打包到 bundle.js 文件中。

Webpack 会给每个模块分配一个唯一的 id 并通过这个 id 索引来访问模块。


下面通过一个项目来手动配置Webpack的方式来学习:

  1. 创建一个空文件夹,运行npm init -y,初始化一个包管理配置文件package.json创建src目录并src下创建index.html和index.js

    image-20210907163730010
  2. 安装jquery使用jq来操作DOMnpm i jquery -S

    import $ from "jquery"
    $(function(){
      $("p").css("background-color","red");
    })
    
  3. 创建webpack.config.js配置文件

    module.exports = {
        mode : "development" // 选择 development 为开发模式, production 为生产模式    
    }
    
  4. package,json配置文件中添加脚本命令,运行npm run dev项目中的会从默认src/index.js文件作为入口,打包项目中的引用到的资源文件,并将结果输出到dist/main.js文件中。

    "scripts": {
      "dev": "webpack"
    },
    
    image-20210907171728757
  5. index.html文件中对index.js的引用修改为引用dist/mian.js,在浏览器中打开就可以看到效果。

    image-20210907172008755

2.1 配置文件

在执行webpack命令时webpack会去寻找项目中的webpack.config.js配置文件根据配置项对项目进行打包。

  • 入口entry入口会指示 webpack 应该使用哪个模块来作为构建其内部依赖图的开始。进入入口起点后webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。
  • loader让 webpack 可以去处理那些非 JavaScript 文件。
  • output属性告诉webpack在哪里输出path它创建的bundles以及如何命名这些文件filename
  • 插件plugins

webpack4.xwebpack5.x的版本中有默认的打包入口文件(src/index.js)和默认的输出文件路径(dist/main.js

const path = require('path');

// 使用 Node.js 中的导出语法,向外导出一个 webpack 的配置对象
module.exports = {   
    //SourceMap 源码与压缩文件的映射文件,生成阶段建议关闭
    devtool: "eval-source-map",
    // development 为开发模式, production 生产模式(会压缩混淆代码)   
    mode: "development", 
    //指定要处理入口文件
    entry: path.join(__dirname,"./src/index.js"),  
    // 指定生成的文件要存放到哪里
    output: { 
        // 存放的目录
        path:path.resolve(__dirname, 'dist/js/'), //表示当前执行脚本所在的目录。(路径)        
        // 生成的文件名
        filename: "bundle.js"     
    }
};

2.2插件

插件在 webpack 的配置信息 plugins 选项中指定,用于完成一些 loader 不能完成的工作。常用插件:

  1. webpack-dev-server:当修改源码时,项目自动打包和构建

    npm install webpack-dev-server --save-dev
    
  2. html-webpack-plugin:项目首次构建完成后自动打开项目文件

    npm i --save-dev html-webpack-plugin
    
  3. clean-webpack-plugin:清除每次打包的输出目录(dist)中原有的文件

    npm install --save-dev clean-webpack-plugin
    

插件dev-server的使用:

需要在package.json文件中的脚本命令中添加serve参数

 "scripts": {
    "dev": "webpack serve",
  },

dev-server插件会启动一个实时打包的http服务所以打开项目的时候是http协议开头

webpack.config.js文件中dev-server插件可以通过devserver节点配置地址和端口:

 "devserver":{
      open: true,
      host: '127.0.0.1',
      port: 9527
  }

image-20220218111225479

image-20220218111548844

dev-server插件会在内存中创建打包好的bundle.js文件,没有存储在物理磁盘中。首页中也会引入内存中的bundle.js文件

插件html-webpack-plugin的使用:

需要在webpack.config.js文件中进行配置

// 1. 导入 html-webpack-plugin 这个插件,得到插件的构造函数
const HtmlPlugin = require('html-webpack-plugin')
// 2. new 构造函数,创建插件的实例对象
const htmlPlugin = new HtmlPlugin({
  // 指定要复制哪个页面
  template: './src/index.html',
  // 指定复制出来的文件名和存放路径
  filename: './index.html'
})
module.exports = {
    ...
    //3. 将插件实例对象配置到webpack中
    plugins:[htmlPlugin]
    ...
}

插件clean-webpack-plugin的使用:

跟上一个插件方法一样,也是创建插件实例,配置plugins配置项.

const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = {
    ...
    //3. 将插件实例对象配置到webpack中
    plugins:[htmlPlugin,new CleanWebpackPlugin()]
    ...
}

完成的配置文件如下:

const path = require('path');
// 1. 导入 html-webpack-plugin 这个插件,得到插件的构造函数
const HtmlPlugin = require('html-webpack-plugin')
// 2. new 构造函数,创建插件的实例对象
const htmlPlugin = new HtmlPlugin({
  // 指定要复制哪个页面
  template: './src/index.html',
  // 指定复制出来的文件名和存放路径
  filename: './index.html'
})
const { CleanWebpackPlugin } = require('clean-webpack-plugin')

// 向外导出一个 webpack 的配置对象
module.exports = {   
    //SourceMap 源码与压缩文件的映射文件生成阶段建议关闭可选值source-map、eval-source-map、nosources-source-map。若配置了该项则打包会生成一个记录映射关系的*.map文件
    devtool: "nosources-source-map",
    // development 为开发模式, production 生产模式(会压缩混淆代码)   
    mode: "development", 
    //指定要处理入口文件
    entry: "./src/index.js",  
    // 指定生成的文件要存放到哪里
    output: { 
        // 存放的目录
        path:path.resolve(__dirname, 'dist'), //表示当前执行脚本所在的目录。(路径)        
        // 生成的文件名
        filename: "js/bundle.js"     
    },
    devServer: {
      open: true,
      host: '127.0.0.1',
      port: 9527
    },
    // 插件的数组,将来 webpack 在运行时,会加载并调用这些插件
    plugins: [htmlPlugin, new CleanWebpackPlugin()],
};

2.3 loader

Webpack 本身只能处理 JS文件如果要处理其他类型的文件就需要使用 loader 进行转换。 比如加载CSS文件需要使用css-loader和style-loader

  • css-loader:遍历css文件找到url()表达式;
  • style-loader:将css代码嵌入页面中的一个style标签中

image-20220218112340763

常用的loader

  1. 样式相关的css-loaderstyle-loaderless-loader
  2. 路径相关的url-loaderfile-loader
  3. ES6相关的babel-loader,使用bable需要创建一个babel.config.js配置文件(设置转码规则)
//css相关的包
npm install --save-dev css-loader
npm install --save-dev style-loader
//less相关的包
npm install less less-loader --save-dev
//图片相关的包
npm install url-loader --save-dev
npm install file-loader --save-dev
//Babel相关的包
npm install -D babel-loader @babel/core @babel/plugin-proposal-decorators

webpack.config.js文件中的module节点添加一个rules数组用于添加loader规则

 module: {//所有第三方文件模块的匹配规则
     rules: [// 定义了不同模块对应的 loader
         //处理css文件的loader,注意loader的顺序执行顺序是从后往前的先css-loader处理将结果交给style-loader最后再交给webpack打包到bundle.js文件中
         { test: /\.css$/, use: ['style-loader', 'css-loader'] },
         // 处理 .less 文件的 loader
         { test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] },
         // 处理图片文件的 loader
         // 如果需要调用的 loader 只有一个则只传递一个字符串也行如果有多个loader则必须指定数组
         // 在配置 url-loader 的时候,多个参数之间,使用 & 符号进行分隔
         { test: /\.jpg|png|gif$/, use: 'url-loader?limit=880&outputPath=images' },
         // 使用 babel-loader 处理高级的 JS 语法
         // 在配置 babel-loader 的时候,程序员只需要把自己的代码进行转换即可;一定要排除 node_modules 目录中的 JS 文件
         // 因为第三方包中的 JS 兼容性,不需要程序员关心
         { test: /\.js$/, use: 'babel-loader', exclude: /node_modules/ }
     ]
 },
resolve: {
	alias: {
		// 告诉 webpack程序员写的代码中@ 符号表示 src 这一层目录,这样查找资源可以从外往里找
        '@': path.join(__dirname, './src/')
    }
}

outputPath参数可以设置编译打包后图片的生成位置;

limit参数用于设置多大的图片需要转码为base64格式

exclude参数排除不需要转码的文件。

使用babel需要在项目根目录中添加一个babel.config.js配置文件,用于指定转换规则:

// 向外导出一个 babel 的配置对象
module.exports = {
    plugins:[
        //以插件的形式,添加支持的转码规则,如下面的修饰器语法,class类语法
        "@babel/plugin-proposal-decorators",
        "@babel/plugin-proposal-class-properties"
    ]
}