webpack

益炜
2023-12-01

初始化WebPack

一、为什么会有webpack?

  1. 因为开发者编写的代码是模块化开发,.less .scss .vue .js等文件

  2. 开发者编写的代码是工程化

    因为浏览器不能解析vue、react 、less 、scss 等工程化,模块化的代码,所以需要webpack 工具,将编写的模块化代码,进行编译/打包,然后在浏览器中运行的编译后或者打包后的代码。

二、webpack是什么?

  1. webpack是自动化构建工具

三、怎么搭建使用webpack的环境

  1. 依赖node.js npm 下载 node.js npm ,npm init -y —> 生成package.json文件。

  2. 安装cli工具 webpack 库

    npm i --save-dev webpack webpack-cli

  3. 测试运行webpack

    局部安装:npx webpack --version

    全局安装:webpack --version

    全局安装 相对整个电脑

    全局会覆盖局部,会导致版本受限制。(推荐局部安装,只相对于当前文件夹)。

  4. 创建webpack配置文件

    webpack.config.js

    module.exports = {}

  5. 运行webpack

    npx webpack

webpack的核心概念

一、entry和output

  1. entry

    entry 配置入口文件

    - 作用:告诉webpack模块化代码的入口文件在哪里

    - webpack 可以通过入口文件 找到所有的模块化文件,进行 编译打包处理

  2. 项目分类

    - 单页面应用 一个 html 一个入口文件

    - 多页面应用 多个 html 多个入口文件

    entry

    - 如何配置单入口

    entry: './src/index.js',
    

    - 如何配置多入口

    xiaomihu:'./src/index.js',
    damihu:'./src/search.js'
    

    output

    > output 配置出口文件

    > 作用: 告诉webpack 编译打包后的代码,应该放在哪里。

    > 换句话:配置是打包后的代码,放在哪个文件以及文件夹中。

    // 配置多出口文件
    output:{
      path:path.resolve(__dirname,'./duorukou'),
      // [name] 动态文件名。赋值的是 entry的key值
      filename:'[name].js'
    }
    

2、loader

需求:在webpack 中使用babel 将高版本js 编译为低版本的js

什么是webpack loader ?

loader 有 n 个

作用:可让webpack 解决一些 非js的模块

babel-loader

作用:在webpack 中使用babel,将高版本js 编译为低版本

npm init

npm install -D babel-loader @babel/core @babel/preset-env

//新建 .babelrc文件
{
   "presets": [
         "@babel/preset-env"
      ]
}

// 在webpack 使用loader:
module: {
// 这里配置loader 
rules: [
//loader 可以配置多个 
//一个loader一个对象
{
  test: /\.m?js$/,
  // 正则匹配文件,匹配那些文件可以使用 babel-loader
  exclude: /(node_modules|bower_components)/,
  // 作用:使用哪一个loader
  // use 赋值  对象 or 函数
  use: {
    loader: 'babel-loader',   // loader 的名字
    options: {  // 可以写 babel-loader 具体参数配置
    presets: ['@babel/preset-env']
       }
      }
     }
   ]
}

3.plugin

为什么有Plugin插件?
因为有一个模块 loader 不能解决所有的模块;以及提供的功能是有限的,所以有了webpack插件。
没有什么问题,是插件解决不了的,如果解决不了,找你们负责人写一个。

插件是什么?
插件是用来解决各种模块编译的
注意:loader和插件可以同时使用

如何使用插件?
需求:希望将html进行打包处理,同时希望html加载对应的js
- 1:下载插件
- 2:使用插件

~~~js
const htmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
    // 数组中元素 为配置的插件
    plugins:[
        new htmlWebpackPlugin({
            template: './index.html',      //template 指定需要被编译的html
            filename: 'index.html',        //filename  配置打包输出的 html文件名
            chunks: ['index'],             // chunks  设置 打包后的html 加载那个打包后js文件
            minify: {                              
                // 删除 index.html 中的注释
                removeComments: false,
                // 删除 index.html 中的4空格
                collapseWhitespace: true,
                // 删除各种 html 标签属性值的双引号
                removeAttributeQuotes: true
            }
        }),
    ]
}

~~~

基础中常用的插件有那些?

用于修改行为
~~~
define-plugin:定义环境变量,在4-7区 分环境中有介绍。

context-replacement-plugin:修改require语句在寻找文件时的默认行为。

ignore-plugin:用于忽略部分文件。

~~~
用于优化

- commons-chunk-plugin:提取公共代码,在4-11提取公共代码中有介绍。
- extract-text-webpack-plugin:提取 JavaScript 中的 CSS 代码到单独的文件中,在1-5使用 Plugin中有介绍。
- prepack-webpack-plugin:通过 Facebook 的 Prepack 优化输出的 JavaScript 代码性能,在 4-13使用 Prepack 中有介绍。
- uglifyjs-webpack-plugin:通过 UglifyES 压缩 ES6 代码,在 4-8压缩代码中有介绍。
- webpack-parallel-uglify-plugin:多进程执行 UglifyJS 代码压缩,提升构建速度。
- imagemin-webpack-plugin:压缩图片文件。
- webpack-spritesmith:用插件制作雪碧图。
- ModuleConcatenationPlugin:开启 Webpack Scope Hoisting 功能,在4-14开启 ScopeHoisting中有介绍。
- dll-plugin:借鉴 DDL 的思想大幅度提升构建速度,在4-2使用 DllPlugin中有介绍。
- hot-module-replacement-plugin:开启模块热替换功能。


其他

- serviceworker-webpack-plugin:给网页应用增加离线缓存功能,在3-14 构建离线应用中有介绍。
- stylelint-webpack-plugin:集成 stylelint 到项目中,在3-16检查代码中有介绍。
- i18n-webpack-plugin:给你的网页支持国际化。
- provide-plugin:从环境中提供的全局变量中加载模块,而不用导入对应的文件。
- web-webpack-plugin:方便的为单页应用输出 HTML,比 html-webpack-plugin 好用。


webpack实现devserve自动化打包

//package.json 
"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack serve --inline --progress",
    "build": "webpack"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.14.6",
    "@babel/preset-env": "^7.14.7",
    "babel-loader": "^8.2.2",
    "html-webpack-plugin": "^5.3.2",
    "webpack": "^5.45.1",
    "webpack-cli": "^4.7.2",
    "webpack-dev-server": "^3.11.2"
  }
}
//webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require("html-webpack-plugin")
module.exports = {
    mode: 'development',
    entry: "./src/main.js",
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: "[name].js"
    },

    module: {
        rules: [
            {
                test: /\.m?js$/,   // 正则匹配文件,匹配那些文件可以使用 babel-loader
                exclude: /(node_modules|bower_components)/,
                use: {
                    loader: 'babel-loader',  // loader 的名字
                    options: { // 可以写 babel-loader 具体参数配置
                        presets: ['@babel/preset-env']
                    }
                }
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './public/index.html',
            filename: 'index.html',
            chunks: ['main']
        })
    ],
    // 配置 webpack-dev-server服务
    devServer: {
        contentBase: path.join(__dirname, 'dist'),
        compress: true,
        port: 9000,
        open: true
    },
    // watch 监听 webpack 已经被编译的代码;可以自动编译
    // webpack-dev-server 默认watch:true 
    watch: true,
    // watchOptions 根据需求 定制 watch 
    watchOptions: {
        // ignored 不监听的文件或文件夹,支持正则匹配
        // 默认为空
        ignored: /node_modules/,
        // 监听到变化发生后会等300ms再去执行动作,防止文件更新太快导致重新编译频率太高
        // 默认为 300ms
        aggregateTimeout: 300,
       
        // 每个多长时间监听一次.开发者编写的代码
        // 默认1000ms
        poll: 3000
    }
}

webpack搭建vue环境

//package.json
"html-webpack-plugin": "^5.3.2",
"vue": "^2.6.14",
"vue-loader": "^15.9.6",
"vue-template-compiler": "^2.6.14",
"webpack": "^5.45.1",
"webpack-cli": "^4.7.2"
const path = require('path');
const VueConfigPlugin = require('vue-loader/lib/plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    mode:'development',
    entry:'./src/main.js',
    output:{
        path:path.resolve(__dirname,'dist'),
        filename:"[name].js"
    },
    module:{
        rules:[
            {
                test:/\.vue$/,
                use:['vue-loader']
            }
        ]
    },
    plugins:[
        new HtmlWebpackPlugin({
            template:'./index.html',
            filename:'index.html',
            chunks:['main']
        }),
        new VueConfigPlugin(),
    ]
}

webpack搭建less环境

### 1安装依赖
- less                         **less 的运行环境**
- less-loader                  **将less编译为 css 的loader**
- css-loader                   **让js解析css代码import/require()**
- style-loader                 **把css插入到dom中**
- mini-css-extract-plugin      **将css离去单独的文件**
- html-webpack-plugin          **打包编译html文件**
- babel-loader                 **在webpack中使用bable工具**
- @babel/presets-env           **babel的预设**
- @babel/core                  **babel的黄健**
- webpack
- webpack-cli                 

`npm i --save-dev less less-loader css-loader style-loader mini-css-extract-plugin html-webpack-plugin babel-loader  @babel/presets-env  @babel/core webpack webpack-cli`

### 创建webpack.config.js
~~~js
module.exports= {
    mode:'development',
    entry:'./src/index.js',
    output:{
        path:path.resolve(__dirname,'dist'),
        filename:'[name].js'
    }
}
~~~
### 配置 loader 
~~~JS
const path = require('path');
const MineCssExtractPlugin = require('mini-css-extract-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports= {
    mode:'development',
    entry:'./src/index.js',
    output:{
        path:path.resolve(__dirname,'dist'),
        filename:'[name].js'
    },
    module:{
        rules:[
            {
                test:/\.less$/i,
                exclude: /(node_modules|bower_components)/, 
                use:[
                    MineCssExtractPlugin.loader,
                    'css-loader',
                    'less-loader'
                ]
            }
        ]
    },
    plugins:[
        new MineCssExtractPlugin({
            filename:'[name].css'
        }),
        new HtmlWebpackPlugin({
            template:'./index.html',
            filename:'index.html',
            chunks:['main']
        })
    ]
}
~~~

webpack搭建scss环境

### 1 安装依赖
- node-sass                      
- sass-loader                        加载 Sass/SCSS 文件并将他们编译为 CS
- css-loader                         解析模块要的 css @import ...
- mini-css-extract-plugin            将css语法提取单独的css 文件
- html-webpack-plugin                打包html
- webpack
- webpack-cli 
- sass

### 2 创建webpack.config.js文件

~~~js
module.exports = {
    mode: 'development',
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].js'
    },
}
~~~

### 3:配置loader和插件

~~~js
const path = require('path');
const MineCssExtractPlugin = require('mini-css-extract-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
    mode: 'development',
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].js'
    },
    module: {
        rules: [
            {
                test: /\.s[ac]ss$/i,
                exclude: /(node_modules|bower_components)/,
                use: [
                    MineCssExtractPlugin.loader,
                    'css-loader',
                    'sass-loader'
                ]
            },

        ]
    },
    plugins: [
        new MineCssExtractPlugin({
            filename: '[name].css'
        }),
        new HtmlWebpackPlugin({
            template: './index.html',
            filename: 'index.html',
            chunks: ['main']
        })
    ]
}
~~~

webpack搭建ts环境

## webpack 搭建ts环境
>ts 需要在typesctipt 运行
> ts 运行过程:  ts_-->编译为js文件--->运行js 

### 1: 安装依赖
- typescript                    是ts的运行环境,将ts编译为 js文件
- awesome-typescript-loader     是webpack 将 ts 语法 变为 js 
- html-webpack-plugin           
- webpack
- webpack-cli


### 2: 创建webpack.config.js文件 
> 初始化文件
~~~js
module.exports = {
    mode:'development',
    entry:'./src/index.ts',
    output:{
        path:path.resolve(__dirname,'dist'),
        filename:"[name].js"
    },
}
~~~
### 3: 配置loader 编译ts 配置创建打包html

~~~js
const path = require("path");
const HtmlWebpack = require('html-webpack-plugin')
module.exports = {
    mode:'development',
    entry:'./src/index.ts',
    output:{
        path:path.resolve(__dirname,'dist'),
        filename:"[name].js"
    },
    module:{
        rules:[
            {
                test: /\.ts$/,
                loader: 'awesome-typescript-loader',
              }
        ]
    },
    plugins:[
        new HtmlWebpack({
            template:'./index.html',
            filename:'index.html',
            chunks:['main']
        })
    ]
}
~~~

### 4: 解决bug
> bug: import {za} from './moduleA' 报错,不能解析这个模块
>    2 如果 import {za} from './moduleA.ts' 开发者工具 报错,语法错误  推荐 import {za} from './moduleA'
>解决: 让webpack 可以解析这种语法  import {za} from './moduleA'

~~~
    resolve:{
        extensions:['.ts','.js']
    },
~~~

webpack搭建svg环境

## webpack5搭建svg环境

>svg 是矢量图。使用svg画的图片,不会怎么放大,都不失真
>1: svg 可以通过 img标签加载
>2: svg 可以作为字体图标
>3: svg 可以用在大屏可视化上 做各种标记点。

>进阶:将svg 做成 icon 组件,并使用webpack 搭建环境 ... 编辑中...


#### 开发实例代码如下
~~~js
// user.svg
<svg  verison="1.1" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
     stroke="#000">
  <circle cx="12" cy="12" r="10" fill="yellow"/>
</svg>
~~~

~~~js
// index.js

import user from'./user.svg';
console.log('index.js run');
console.log(user)
const div = document.createElement("div");
div.style.width = '300px';
div.style.height = '300px';
div.style.border = '3px solid red';
// svg 作为背景图片
div.style.background = `url(${user})`;
var body = document.querySelector('body');
body.appendChild(div)

const img = document.createElement('img');
img.src = user;
body.appendChild(img)
~~~
~~~
创建空的 index.html
~~~

#### 初始项目
>npm init -y

#### 初始化安装依赖
`npm i --save-dev webpack@5.45.1 webpack-cli@4.7.2 html-webpack-plugin` 
#### 初始化webpack.config.js文件
~~~js
const path = require('path');

module.exports = {
    mode: "development",
    entry: "./src/index.js",
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: "[name].js",
    },
}
~~~
#### 1配置 svg  2打包 html

~~~js
module.exports = {
    mode: "development",
    entry: "./src/index.js",
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: "[name].js",
    },
     module: {
        rules: [
            {
                test: /\.svg/,
                type: 'asset/inline',

                // webpack5 以下版本才支持这个写法
                // use:['svg-inline-loader']
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './index.html',
            filename: 'index.html'
        })
    ]
}
~~~

#### 运行 webpack
>npm run build
>实际上运行: npx webpack

#### 运行打包后的代码,测试是否有问题

webpack构建react

//package.json


"@babel/core": "^7.14.8",
"@babel/preset-react": "^7.14.5",
"babel-loader": "^8.2.2",
"html-webpack-plugin": "^5.3.2",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"webpack": "^5.45.1",
"webpack-cli": "^4.7.2"


//webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
    mode: "development",
    entry: "./src/main.js",
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: "[name].js",
    },
    module:{
        rules:[
            {
                test: /\.m?js$/,
                exclude: /(node_modules|bower_components)/, 
                use: {
                    loader: 'babel-loader',  
                    options: { 
                        presets: ['@babel/preset-react']
                    }
                }
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './index.html',
            filename: 'index.html'
        })
    ]
}

为单页面应用生成html

//package.json


"@babel/core": "^7.14.8",
"@babel/preset-react": "^7.14.5",
"babel-loader": "^8.2.2",
"html-webpack-plugin": "^5.3.2",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"web-webpack-plugin": "^4.6.7",
"webpack": "^5.45.1",
"webpack-cli": "^4.7.2"


//webpack.config.js
const path = require('path');
// webpack5 不支持 使用 html-webpack-plugin
// const webWebpackPlugin = require('web-webpack-plugin');
const HtmmlWebpackPlugin = require('html-webpack-plugin')

// webpack5 已经废弃
// const UglifyJsPlugin = require('webpack/lib/optimize/UglifyJsPlugin');
// const DefinePlugin = require('webpack/lib/DefinePlugin');


module.exports = {
    mode: "development",
    entry: "./src/main.js",
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: "[name].js",
    },
    module: {
        rules: [
            {
                test: /\.m?js$/,
                exclude: /(node_modules|bower_components)/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-react']
                    }
                }
            }, {
                test: /\.html/,
                type: 'asset/resource',
                generator: {
                    filename: 'static/[hash][ext][query]'
                }
            }
        ]
    },
    plugins:[
        new HtmmlWebpackPlugin({
            template:'./tast.html',
            filename:'index.html'
        })
    ]
}
 类似资料: