webpack篇

在这里插入图片描述

理解webpack

最重要的四大模块

  • 入口
  • 出口
  • 装载器loader: webpack只能理解js和json文件,使用loader之后可以处理其他类型的文件,并将他们转转成webpack可识别的模块。比如babel-loader: 将es6转成es5,react-loader: 加载react文件,vue-loader同理,以及css-loader,加载css文件,sass-loader将sass代码转成css代码,image-loader,ts-loader:将ts转成js代码等
  • 插件plugin:打包优化,资源管理,注入环境变量。例如

创建webpack工程

  1. 生成package.json文件
    npm init -y

  2. 安装webpack
    cnpm install -D webpack webpack-cli
    -D -S 把依赖包保存在package.json文件中
    -S 保存的包是需要发布的
    -D 是不需要发布的
    默认安装的是最新版本, 版本过高 webpack@4
    node自带npm npx
    cnpm和yarn不是node自带的

webpack零配置

打包命令: npx webpack
默认入口 src/index.js
默认出口 dist/main.js
只打包js,生成main.js

指定webpack配置

let path = require("path");
let HtmlWebpackPlugin = require("html-webpack-plugin");

// module 是node 的语法,webpack是基于node的
module.exports = {
  // 入口
  entry: "./src/index.js",
  /**
   * 打包的模式,只有两种,一种是production生产模式,
   * 这个打包之后代码是压缩之后的,不便于我们查看;另一种development 开发模式,打包之后代码没有压缩,
   * 在浏览器中可以查看代码,便于我们调试
   *  */
  mode: "development",
  // 出口
  output: {
    // __dirname 当前路径
    path: path.resolve(__dirname, "dist"), // 绝对路径 ,在根目录生成一个dist的文件夹,里面是打包之后的文件
    filename: "index.js", // 修改打包之后的js文件名
  },
  devServer: {
    // 配置webpack-dev-server 开发使用
    port: 8081, // 配置web服务器端口,端口不能相同
    open: true, // 启动成功之后自动打开浏览器
    progress: true, // 进度
    contentBase: "./dist", // 指定web服务的根目录,服务一打开就直接去dist文件夹下找index.html文件,有就直接打开
  },
  plugins: [
    // HtmlWebpackPlugin这个插件是将html模板打包进dist文件夹里,因为webpack 零配置只打包js文件
    new HtmlWebpackPlugin({
      template: "./src/index.html", // 指定输出的文件模板
      filename: "index.html", // 修改打包之后的模板名称,最好使用index.html,
    }),
  ],
};

注意:HtmlWebpackPlugin下的filename最好命名为index.html,因为系统会自动去找index.html,如果不改成其它名字,访问地址的时候就不会直接显示页面,也是显示项目文件,让你自己去选择html.效果就如下了,这个效果是不好的,记住
在这里插入图片描述

如何启动服务 webpack-dev-server

  • 首先安装webpack-dev-server命令
npm install -D webpack-dev-server
yarn add webpack-dev-server -D
  • 然后在package.json文件下scripts写如下代码
// package.json
{
  "name": "01",
  "version": "1.0.0",
  "description": "- 入口 - 出口 - 装载器loader - 插件plugin",
  "main": "index.js",
  "scripts": {
    "start": "webpack serve",  // 执行命令 npm start 
    "dev": "webpack serve",// 命令npm run dev ,执行的命令其实是webpack serve
    "build": "webpack"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "html-webpack-plugin": "^5.3.1",
    "webpack": "^5.24.4",
    "webpack-cli": "^4.5.0",
    "webpack-dev-server": "^3.11.2"
  }
}
  • 最后你就可以使用命令(npm start or npm run dev)启动你的项目服务,项目就跑起来拉

配置webpack-dev-server 开发使用

在webpack.config.js文件里

devServer: {
    // 配置webpack-dev-server 开发使用
    port: 8081, // 配置web服务器端口,端口不能相同
    open: true, // 启动成功之后自动打开浏览器
    progress: true, // 进度
    contentBase: "./dist", // 指定web服务的根目录,服务一打开就直接去dist文件夹下找index.html文件,有就直接打开
  },

css /js/es6 es7支持 装载器 loader,插件plugin

css(装载器)

  1. webpack默认只加载js,不支持加载css;

  2. 需要css装载器 css-loader;

  3. 再 安装style-loader 把css直接添加到html的

**装载器执行顺序 **

先加载 css 后整合到html的< style>执行顺序:从右到从

 // 先安装css-loader ,style-loader ,yarn add css-loader -D
 module: {
    rules: [
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"], // 执行顺序是从右向左
      },
    ],
  },

less (装载器)

cnpm i -D less less-loader
use: ['style-loader','css-loader','less-loader'] 
// 具体
module: {
      {
        test: /\.less$/,
        use: ["style-loader", "css-loader", "less-loader"], // 现将less文件装载到less-loader转化成css ,然后再装载到css 里,最后渲染到style 标签上
      },
    ],
  },

抽取css作为单独的文件 mini-css-extract-plugin(插件)

  • 将 CSS 提取为独立的文件的插件,对每个包含 css 的 js 文件都会创建一个 CSS 文件,支持按需加载 css 和 sourceMap.只能用在 webpack4 中,对比另一个插件 extract-text-webpack-plugin 有以下特点:
  • 异步加载
  • 不重复编译,性能更好
  • 更容易使用
  • 只针对 CSS
    这个插件应该只用在生产环境配置,并且在 loaders 链中不使用 style-loader, 而且这个插件暂时不支持 HMR
let MiniCssExtractPlugin = require('mini-css-extract-plugin');
use: [MiniCssExtractPlugin.loader, 'css-loader']
new MiniCssExtractPlugin({
	filename: 'index.css'
})

# css js压缩

css:optimize-css-assets-webpack-plugin 或者 css-minimizer-webpack-plugin

在指定css压缩后 js压缩就无效了,需要再次指定js: terser-webpack-plugin

let TerserPlugin = require('terser-webpack-plugin') // js压缩
let OptimizeCssPlugin = require('optimize-css-assets-webpack-plugin') //css压缩
let CssPlugin = require('css-minimizer-webpack-plugin') // css压缩
optimization: {
     //压缩
     minimizer: [new TerserPlugin(), new CssPlugin()] // [new TerserPlugin(), new OptimizeCssPlugin()]
   },

** es6 es7支持**

  • 首先需要babel-loader的装载器,@bable/core,@bable/preset-env(转换器,将se7转es6或者将es6转es5的)
  • 需要一个插件 babel-plugin-proposal-decorators 这个就是es7上的注解@xx,将这个编译成es6的插件
    安装命令:
yarn add babel-loader -D
yarn add  @bable/core  -D
yarn add @bable/preset-env  -D 
yarn add @babel-plugin-proposal-decorators  -D

babel-loader 插件 ;可以在babel官网上查询相应的插件,如@babel/plugin-proposal-decorators

module:{
	rules:[
	{
	     test:/\.js$/,
	     use: {
	     	loader: 'babel-loader',
	         options: {
	             presets: [
	             	"@babel/preset-env"
	             ],
	     		"plugins": [
	     		// es6,es7 转化插件
	     			["@babel/plugin-proposal-decorators", { "legacy": true }],
	    			 ["@babel/plugin-proposal-class-properties", { "loose" : true }]
	    		 ]
	    	 }
	     }
	 },
	]
}
 

js 模块化

commonjs:导出:module.exports ;导入:require

es6: 导出: export default, export xxx ;导入: import xx from xxx
使用上面的装载器之后就可以直接打包成功

tree shaking 【摇树】(过滤掉没有调用到的代码)

webpack4有这个功能,很弱,只支持当前js文件中无用的代码;webpack5加强了这个功能。

如:a.js(有无用的代码, a=1,b=2)---》被index.js引入(只引了部分,输出a)

会检查整个链路中属性的使用情况,确定没有使用就去掉。

但是只会在生产模式下才会过滤,开发模式都会打包。

webpack.config 1

// webpack.config
let path = require('path');
let HtmlWebpackPlugin = require("html-webpack-plugin"); // html 插件 自动在html 引入js文件
let MiniCssExtractPlugin = require('mini-css-extract-plugin'); //插件 抽取css作为单独的文件 
let TerserPlugin = require('terser-webpack-plugin') // js压缩
let OptimizeCssPlugin = require('optimize-css-assets-webpack-plugin') // css压缩
let CssPlugin = require('css-minimizer-webpack-plugin') // css压缩

module.exports = {
    optimization: {
        //压缩
        minimizer: [new TerserPlugin(), new CssPlugin()]
    },
    //入口  出口  loader  plugin
    entry: "./src/index.js", //输入
    mode: 'production',  //production development // 模式
    output: { // 输出
        //__dirname 表示当前目录
        path: path.resolve(__dirname, "dist"),  //绝对路径
        filename: "index.js"                    //输出的文件名
    },
    devServer: {  //配置webpack-dev-server
        port: 8083,   //配置web服务端口
        open: true,   //自动打开浏览器
        progress: true,   //进度
        contentBase: './dist'  //指定web服务器的根目录
    },
    module: { //装载器
        rules: [
            {
                test:/\.js$/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: [
                            "@babel/preset-env"
                        ],
                        "plugins": [
                            ["@babel/plugin-proposal-decorators", { "legacy": true }],
                            ["@babel/plugin-proposal-class-properties", { "loose" : true }]
                        ]
                    }
                }
            },
            {
                test: /\.css$/,
                // use: ['style-loader','css-loader'] // 执行顺序:从右到从,其他规则一直
                use: [MiniCssExtractPlugin.loader, 'css-loader']
            },
            {
                test: /\.less$/,
                // use: ['style-loader','css-loader','less-loader']
                use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader']
            }
        ]
    },
    plugins: [  // 插件
        new HtmlWebpackPlugin({
            template: './src/index.html',   //指定输出的文件模板
            filename: 'index.html'           //指定输出dist的文件名
        }),
        new MiniCssExtractPlugin({
            filename: 'index.css'
        })
    ]
}

package.json1

{

 "name": "01",

 "version": "1.0.0",

 "description": "- 入口 - 出口 - 装载器loader - 插件plugin",

 "main": "index.js",

 "scripts": {

  "start": "webpack serve",

  "dev": "webpack serve",

  "build": "webpack"

 },

 "keywords": [],

 "author": "",

 "license": "ISC",

 "devDependencies": {

  "@babel/core": "^7.13.10",

  "@babel/plugin-proposal-decorators": "^7.13.5",

  "@babel/preset-env": "^7.13.10",

  "babel-loader": "^8.2.2",

  "css-loader": "^5.1.3",

  "css-minimizer-webpack-plugin": "^1.3.0",

  "html-webpack-plugin": "^5.3.1",

  "less": "^4.1.1",

  "less-loader": "^8.0.0",

  "mini-css-extract-plugin": "^1.3.9",

  "optimize-css-assets-webpack-plugin": "^5.0.4",

  "style-loader": "^2.0.0",

  "terser-webpack-plugin": "^5.1.1",

  "webpack": "^5.24.4",

  "webpack-cli": "^4.5.0",

  "webpack-dev-server": "^3.11.2"

 }

}

打包生成文件动态名字及hash

没有分类存储 js css,可以output.filename: “js/index.js”,filename: ‘css/index.css’ 这样解决

在这里插入图片描述
在这里插入图片描述

使用hash值的时候,第一次打包发布, index.123.js 文件会被浏览器自动缓存。

当第二次修改打包发布,若文件名不变,浏览器会不会下载新的文件?

答案是不会。浏览器304代表的是缓存,如果文件名不变,浏览器觉得文件没更新,就不会从服务器重新请求。

hash—内容如果有改变,hash值就会改变

 output: {
        //__dirname 表示当前目录
        path: path.resolve(__dirname, "dist"),  //绝对路径
       // filename: "js/index.js"     //    index.js           //输出的文件名
        filename: "js/[name].[hash:4].js"                    //hash 输出动态文件名
    },
    plugins: [
    // HtmlWebpackPlugin这个插件是将html模板打包进dist文件夹里,因为webpack 零配置只打包js文件
    new HtmlWebpackPlugin({
      template: "./src/index.html", // 指定输出的文件模板
      filename: "index.html", // 修改打包之后的模板名称,最好使用index.html,
    }),
    new MiniCssExtractPlugin({
      filename: "css/[name].[hash:4].css", // //hash 输出动态文件名
    }),
  ]

全局变量

使用import导入,需要在使用的地方都要导入一次

全局变量配置

webpack.ProvidePlugin能够给所有组件注入全局变量$

plugins:[
 new webpack.ProvidePlugin({   //全局变量
   $: 'jquery'
 })
]

问题:打包时会把jquery等三方包一起打包,怎么把第三方包剔除出去呢,不要打包第三方包?

打包时,可以使用externals把三方包拆开,但是需要在Html上手动引入三方包,可以使用cdn有钱最好使用收费的三方报,比较稳定;把第三方下载下来放到你的目录,但是这样子会增加你的带宽;

plugins:[],
externals: {   //排除三方包
        jquery: '$'
 }

图片

图片的加载需要 file-loader/url-loader 装载器

file-loader 默认使用es6模块化

\1. 使用js方式导入

\2. 使用css方式导入

css文件在根目录ok

css文件在css目录中,需要打包时将图片加上…/前缀,
在这里插入图片描述

图片加载到指定目录images
在这里插入图片描述

\3. 在html上加载图片,使用标签
在这里插入图片描述

<body>

    <div id="test">webpack package</div>

    <div id="test2">webpack package</div>

  html上加载图片

    <img src="./1.jpeg" />

</body>

配置文件

// 图片 js引入
var jpg = require("./1.jpeg");
console.log(jpg)
let img = new Image();
img.src = jpg;
// file-loader使用es6模块化
// var jpg = require("./1.jpeg"); 这里用import 引入需要 jpg.default吗?待测试。
// img.src = jpg.default;
// file-loader使用commonjs
document.body.appendChild(img) 

//a.css
#test {
    color: brown;
    width: 300px;
    height: 300px;
    background: url('./2.jpeg');
}

// webpack.config
 {
	 test: /\.css$/,
 	// use: ['style-loader','css-loader']
     use: [{
    	 loader: MiniCssExtractPlugin.loader,
         options: {
         	publicPath: '../'  //给css中所有图片添加相对路径 如果less等也用到图片 也要配置
         						// 配置路径根据打包后的文件路径配置,如果都是根目录就不需要配,这里因								// 为在css文件夹下
         }
     }, 'css-loader', 'postcss-loader']
  },
 {
 	test: /\.(jpeg|jpg|png)$/,
    
     // use: {
     //     loader: 'file-loader',
     //     options: {
     //         esModule: false,   //使用commonjs
     //         outputPath: 'images'  //把图片加载到目录下
     //     }
     // }
 },

图片加载转换

使用url-loader代替file-loader, url-loader包含了file-loader

    1. 对于小于多少的图片,可以打包时转换为base64,图片转为base64可以减少http请求
    1. 对于较大的图片,直接提供url,让浏览器下载,可以使用cdn优化
{
test: /\.(jpeg|jpg|png)$/,
 use: {
    	 loader: 'url-loader',
         options: {
             esModule: false,
             outputPath: 'images', // 图片加载到指定目录images
             limit: 20*1024  //小于20kb的图片转base64
         }
     }
}

样式兼容性

w3c提出一些新样式,css3包括很新标准样式 aaa

浏览厂商:微软ie edge chrome ff

chrome: webkit-aaa

ie: ie-aaa

等到所有的厂商都支持后,就可以去掉前缀;

使用兼容性插件目的就是生成所有厂商前缀的样式。

1.配置postcss.config.js

2.配置postcss-loader

3.配置package.json中browserslist

1 // postcss.config.js 根目录
module.exports = {
    plugins: [
        require('autoprefixer')
    ]
}
2 //配置postcss-loader
 {
 	test: /\.css$/,
 		// use: ['style-loader','css-loader']
     use: [{
     	loader: MiniCssExtractPlugin.loader,
         options: {
            publicPath: '../'  //给css中所有图片添加相对路径
         }
     }, 'css-loader', 'postcss-loader'] //配置postcss-loader
 },
 {
 	test: /\.less$/,
	 // use: ['style-loader','css-loader','less-loader']
	 use: [
         MiniCssExtractPlugin.loader, 
         'css-loader',
         'less-loader', 
         'postcss-loader'
	 ] //配置postcss-loader
 }
3 //配置package.json中browserslist
对于部分配置参数做一些解释:
" >1%" :代表着全球超过1%人使用的浏览器
“last 2 versions” : 表示所有浏览器兼容到最后两个版本
“not ie <=8” :表示IE浏览器版本大于8(实则用npx browserslist 跑出来不包含IE9 )
“safari >=7”:表示safari浏览器版本大于等于7

"browserslist": [
    "> 1%",
    "last 100 versions",
    "not ie <= 8"
 ]

webpack.config 2

let path = require('path');
let HtmlWebpackPlugin = require("html-webpack-plugin");
let MiniCssExtractPlugin = require('mini-css-extract-plugin');
let TerserPlugin = require('terser-webpack-plugin')
let OptimizeCssPlugin = require('optimize-css-assets-webpack-plugin')
let CssPlugin = require('css-minimizer-webpack-plugin')
let webpack = require("webpack")

module.exports = {
    optimization: {
        //压缩
        minimizer: [new TerserPlugin(), new CssPlugin()]
    },
    //入口  出口  loader  plugin
    entry: "./src/index.js",
    mode: 'production',  //production
    output: {
        //__dirname 表示当前目录
        path: path.resolve(__dirname, "dist"),  //绝对路径
        filename: "js/[name].[hash:4].js"                    //输出的文件名
    },
    devServer: {  //配置webpack-dev-server
        port: 8083,   //配置web服务端口
        open: true,   //自动打开浏览器
        progress: true,   //进度
        contentBase: './dist'  //指定web服务器的根目录
    },
    module: {
        rules: [
            {
                test:/\.html$/,
                use: 'html-withimg-loader'
            },
            {
                test: /\.(jpeg|jpg|png)$/,
                use: {
                    loader: 'url-loader',
                    options: {
                        esModule: false,
                        outputPath: 'images',
                        limit: 20*1024  //小于20kb的图片转base64
                    }
                }
                // use: {
                //     loader: 'file-loader',
                //     options: {
                //         esModule: false,   //使用commonjs
                //         outputPath: 'images'  //把图片加载到目录下
                //     }
                // }
            },
            {
                test:/\.js$/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: [
                            "@babel/preset-env"
                        ],
                        "plugins": [
                            ["@babel/plugin-proposal-decorators", { "legacy": true }],
                            ["@babel/plugin-proposal-class-properties", { "loose" : true }]
                        ]
                    }
                }
            },
            {
                test: /\.css$/,
                // use: ['style-loader','css-loader']
                use: [{
                    loader: MiniCssExtractPlugin.loader,
                    options: {
                        publicPath: '../'  //给css中所有图片添加相对路径
                    }
                }, 'css-loader', 'postcss-loader']
            },
            {
                test: /\.less$/,
                // use: ['style-loader','css-loader','less-loader']
                use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader', 'postcss-loader']
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html',   //指定输出的文件模板
            filename: 'index.html'           //指定输出dist的文件名
        }),
        new MiniCssExtractPlugin({        //抽取css为单独的文件
            filename: 'css/[name].[hash:4].css'
            // filename: 'index.css'
        }),
        new webpack.ProvidePlugin({   //全局变量
            $: 'jquery'
        })
    ],
    externals: {   //排除三方包
        jquery: '$'
    }
}

package.json2

{
  "name": "01",
  "version": "1.0.0",
  "description": "- 入口 - 出口 - 装载器loader - 插件plugin",
  "main": "index.js",
  "scripts": {
    "start": "webpack serve",
    "dev": "webpack serve",
    "build": "webpack"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.13.10",
    "@babel/plugin-proposal-decorators": "^7.13.5",
    "@babel/preset-env": "^7.13.10",
    "autoprefixer": "^10.2.5",
    "babel-loader": "^8.2.2",
    "css-loader": "^5.1.3",
    "css-minimizer-webpack-plugin": "^1.3.0",
    "file-loader": "^6.2.0",
    "html-webpack-plugin": "^5.3.1",
    "html-withimg-loader": "^0.1.16",
    "less": "^4.1.1",
    "less-loader": "^8.0.0",
    "mini-css-extract-plugin": "^1.3.9",
    "optimize-css-assets-webpack-plugin": "^5.0.4",
    "postcss-loader": "^5.2.0",
    "style-loader": "^2.0.0",
    "terser-webpack-plugin": "^5.1.1",
    "url-loader": "^4.1.1",
    "webpack": "^5.24.4",
    "webpack-cli": "^4.5.0",
    "webpack-dev-server": "^3.11.2"
  },
  "dependencies": {
    "jquery": "^3.6.0"
  },
  "browserslist": [
    "> 1%",
    "last 100 versions",
    "not ie <= 8"
  ]
}

多页面应用打包

  • 需要指定多个入口
  • 多个出口
  • 多个HtmlWebpackPlugin用于生成多个页面
  • 需要chunks指定需要引入的js

webpack.config.js

let path = require('path');
let HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
    //多页面应用  多个入口  打包要生成多个html
    entry: {
        index: "./src/index.js",
        other: "./src/other.js"
    },
    mode: 'development',  //production
    //出口 也需要输出多个文件
    output: {
        //__dirname 表示当前目录
        path: path.resolve(__dirname, "dist"),  //绝对路径
        filename: "[name].js"                    //输出的文件名
    },
    devServer: {  //配置webpack-dev-server
        port: 8083,   //配置web服务端口
        open: true,   //自动打开浏览器
        progress: true,   //进度
        contentBase: './dist'  //指定web服务器的根目录
    },
    plugins: [
        //主页  里面引入的js也不一样
        new HtmlWebpackPlugin({
            template: './src/index.html',   //指定输出的文件模板
            filename: 'index.html',           //指定输出dist的文件名
            chunks: ['index']               //指定页面需要的js
        }),
        //订单页  比如需要2个js
        new HtmlWebpackPlugin({
            template: './src/index.html',   //指定输出的文件模板
            filename: 'other.html',           //指定输出dist的文件名
            chunks: ['index','other']
        })
    ]
}

多环境打包

# webpack 多环境打包

- 开发环境, 发布测试环境, 发布线上环境

- 开发服务器 http://192.168.1.100:8080

测试服务器 http://192.168.1.200:8080

线上服务器 http://xxxxxxxxxxxx:8080

webpack.base.js

// 父模板 webpack.base.js
let path = require('path');
let HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
    //入口  出口  loader  plugin
    entry: "./src/index.js",
    output: {
        //__dirname 表示当前目录
        path: path.resolve(__dirname, "dist"),  //绝对路径
        filename: "index.js"                    //输出的文件名
    },
    devServer: {  //配置webpack-dev-server
        port: 8083,   //配置web服务端口
        open: true,   //自动打开浏览器
        progress: true,   //进度
        contentBase: './dist'  //指定web服务器的根目录
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html',   //指定输出的文件模板
            filename: 'index.html'           //指定输出dist的文件名
        })
    ]
}

webpack.dev.js

//开发模式
let path = require('path');
let webpack = require("webpack");
let {merge} = require('webpack-merge')
let base = require('./webpack.base')

module.exports = merge(base, {
    mode: 'development',  //production
    plugins: [
        // 定义webpack变量
        new webpack.DefinePlugin({
            DEV_ENV: JSON.stringify('dev url')
        })
    ]
})

webpack.prod.js

//生产模式
let path = require('path');
let webpack = require("webpack");
let {merge} = require('webpack-merge')
let base = require('./webpack.base')

module.exports = merge(base, {
    mode: 'production',  //production
    plugins: [
        // 定义webpack变量
        new webpack.DefinePlugin({
            DEV_ENV: JSON.stringify('prod')
        })
    ]
})

webpack.test.js

//生产模式
let path = require('path');
let webpack = require("webpack");
let {merge} = require('webpack-merge')
let base = require('./webpack.base')

module.exports = merge(base, {
    mode: 'production',  //production
    plugins: [
        // 定义webpack变量
        new webpack.DefinePlugin({
            DEV_ENV: JSON.stringify('test')
        })
    ]
})

package.json

{
  "name": "01",
  "version": "1.0.0",
  "description": "- 入口 - 出口 - 装载器loader - 插件plugin",
  "main": "index.js",
  "scripts": {
    "start": "webpack serve",
    "dev": "webpack serve",
    "build:test": "webpack --config webpack.dev.js",
    "build:prod": "webpack --config webpack.prod.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "html-webpack-plugin": "^5.3.1",
    "webpack": "^5.24.4",
    "webpack-cli": "^4.5.0",
    "webpack-dev-server": "^3.11.2",
    "webpack-merge": "^5.7.3"
  }
}

src下的index.js

console.log(DEV_ENV)
if (DEV_ENV === 'dev') {
    console.log("这是测试环境, 输出大量的日志,便于定位问题")
} else {
    console.log("这是线上环境, 减少日志输出 ")
}

# 模板模式

\1. 先要有一个模板,模板里面会实现大部分通用页面

webpack.base.js

\2. 子文件 继承 模板,并且自己扩展

根据不同的环境使用不同的文件

webpack.dev.js 开发

webpack.prod.js 线上

\3. 最终得到一个 子和父的 合体

打包只需要输入不同的命令

测试: npm run build:test

线上:npm run build:prod

跨域和热加载

# 什么是跨域?

协议 域名 端口 三者只要有不同就是跨域

http://www.baidu.com:80 默认80

https://www.baidu.com:443 默认443

# 搭建服务端

使用express搭建服务端

启动: node server.js

# 多种跨域处理

- cors 在数据交互中讲过 属于后端跨域,推荐后端来做跨域处理

- 代理 nginx 处理跨域 推荐

- webpack处理跨域:前两种可以的情况下,不推荐使用webpack做跨域处理,这种方法打包之后就失效了,只适合开发的时候

\1. 使用proxy代理方式处理跨域

devServer:{
 proxy: {
            //匹配以/api开头的请求并跳转到target
            '/api': {
                target: 'http://localhost:3000',
                pathRewrite: {'/api': ''}      //去掉前缀
            },
            '/my': {
                target: 'http://localhost:3000'
            }
  },
}

\2. 使用webpack插件把前后端合在一起,这是在后端那边处理,后端启动服务的时候,也一并将前端服务启动

// 将前后端合并
let webpack = require("webpack");
let middle = require("webpack-dev-middleware");
let config = require('./webpack.config');
let compiler = webpack(config)
app.use(middle(compiler))

# 热更新

webpack提供的特性,不用刷新,不用重启,直接将更新的内容加载到页面上了

devServer: {  //配置webpack-dev-server
        port: 8083,   //配置web服务端口
        hot: true,     //开启热更新
        proxy: {
            //匹配以/api开头的请求并跳转到target
            '/api': {
                target: 'http://localhost:3000',
                pathRewrite: {'/api': ''}      //去掉前缀
            },
            '/my': {
                target: 'http://localhost:3000'
            }
        },
        open: true,   //自动打开浏览器
        progress: true,   //进度
        contentBase: './dist'  //指定web服务器的根目录
    },

server.js

//  node express
let express = require('express')

let app = express();

// 将前后端合并
let webpack = require("webpack");
let middle = require("webpack-dev-middleware");
let config = require('./webpack.config');
let compiler = webpack(config)
app.use(middle(compiler))

app.get('/api/user', (req, res)=> {
    res.json({name:'api user'})
})

app.get('/my/user', (req, res)=> {
    res.json({name:'my user'})
})

app.get('/my/user2', (req, res)=> {
    res.json({name:'my user'})
})

app.get('/user', (req, res)=> {
    res.json({name:'no api user'})
})

app.listen(3000, ()=>{
    console.log("服务已启动, 端口3000")
})

webpack.config.js

let path = require('path');
let HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
    //入口  出口  loader  plugin
    entry: "./src/index.js",
    mode: 'development',  //production
    output: {
        //__dirname 表示当前目录
        path: path.resolve(__dirname, "dist"),  //绝对路径
        filename: "index.js"                    //输出的文件名
    },
    devServer: {  //配置webpack-dev-server
        port: 8083,   //配置web服务端口
        hot: true,     //开启热更新
        proxy: {
            //匹配以/api开头的请求并跳转到target
            '/api': {
                target: 'http://localhost:3000',
                pathRewrite: {'/api': ''}      //去掉前缀
            },
            '/my': {
                target: 'http://localhost:3000'
            }
        },
        open: true,   //自动打开浏览器
        progress: true,   //进度
        contentBase: './dist'  //指定web服务器的根目录
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html',   //指定输出的文件模板
            filename: 'index.html'           //指定输出dist的文件名
        }),
        new HtmlWebpackPlugin({
            template: './src/index.html',   //指定输出的文件模板
            filename: 'main.html'           //指定输出dist的文件名
        })
    ]
}

package.json

{
  "name": "01",
  "version": "1.0.0",
  "description": "- 入口 - 出口 - 装载器loader - 插件plugin",
  "main": "index.js",
  "scripts": {
    "start": "webpack serve",
    "dev": "webpack serve",
    "build": "webpack"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "express": "^4.17.1",
    "html-webpack-plugin": "^5.3.1",
    "webpack": "^5.24.4",
    "webpack-cli": "^4.5.0",
    "webpack-dev-middleware": "^4.1.0",
    "webpack-dev-server": "^3.11.2"
  }
}

index.js

//ajax
let xhr = new XMLHttpRequest()

// xhr.open('get', 'http://localhost:3000/api/user');
xhr.open('get', '/api/user')

xhr.onload = function () {
  console.log(xhr.response)
}

xhr.send()

//ajax
let xhr2 = new XMLHttpRequest()

// xhr.open('get', 'http://localhost:3000/api/user');
xhr2.open('get', '/my/user')

xhr2.onload = function () {
  console.log(xhr2.response)
}

xhr2.send()

// 热更新
import test from './test'
console.log(test)

//判断热更新是否开启
if (module.hot) {
  module.hot.accept('./test', () => {
    console.log('文件更新了')
    let s = require('./test')
    console.log(s.default)
  })
}

test.js

export default "test111"
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,下面是一关于Webpack的博客: Webpack是一款现代化的前端构建工具,它可以将各种资源(如JavaScript、CSS、图片等)打包成一系列资源文件,使得前端开发变得更简单、更高效。Webpack是一个非常强大的工具,但是它的配置也比较复杂。在本文中,我们将介绍Webpack的基本使用方法和配置。 一、安装Webpack 在使用Webpack之前,我们需要先安装它。可以使用npm或者yarn来安装Webpack,例如: ``` npm install webpack webpack-cli --save-dev ``` 安装完成后,我们就可以开始使用Webpack了。 二、使用Webpack Webpack的使用非常简单,只需要在命令行中输入webpack命令,就可以进行打包。例如: ``` webpack ./src/index.js ./dist/bundle.js ``` 上面的命令将src目录下的index.js文件打包成dist目录下的bundle.js文件。 但是,使用命令行进行打包并不是一个很好的选择,因为我们需要手动输入命令,而且命令的参数也比较复杂。因此,我们可以使用Webpack配置文件来进行打包。 三、Webpack配置文件 Webpack的配置文件是一个JavaScript文件,通常命名为webpack.config.js。在该文件中,我们可以配置入口文件、输出文件、Loaders、Plugins等内容。 1. 入口文件 入口文件是Webpack的入口点,Webpack会根据入口文件进行打包。在配置入口文件时,我们可以使用entry属性来指定入口文件的路径。例如: ``` module.exports = { entry: './src/index.js' } ``` 上面的代码中,我们将入口文件指定为src目录下的index.js文件。 2. 输出文件 输出文件是Webpack打包后生成的文件,我们可以通过output属性来指定输出文件的路径和文件名。例如: ``` const path = require('path') module.exports = { entry: './src/index.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js' } } ``` 上面的代码中,我们将输出文件指定为dist目录下的bundle.js文件,使用了path.resolve()方法来获取绝对路径。 3. Loaders Loaders是Webpack中用来处理各种文件类型的模块。在Webpack中,所有的文件都可以看作是模块,而Loaders就是用来处理这些模块的。例如,我们可以使用babel-loader来处理ES6语法,css-loader来处理CSS文件,file-loader来处理图片等。 在配置Loaders时,我们需要使用module属性,并在其中配置rules属性。例如: ``` module.exports = { entry: './src/index.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js' }, module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'] } } }, { test: /\.css$/, use: ['style-loader', 'css-loader'] }, { test: /\.(png|jpe?g|gif)$/i, use: [{ loader: 'file-loader', options: { name: '[name].[ext]', outputPath: 'images/' } }] } ] } } ``` 上面的代码中,我们配置了三个Loaders,分别用来处理JavaScript、CSS和图片文件。其中,babel-loader用来处理ES6语法,css-loader用来处理CSS样式,file-loader用来处理图片。 4. Plugins Plugins是Webpack中用来处理各种任务的插件。在Webpack中,我们可以使用各种各样的插件来扩展Webpack的功能,例如,我们可以使用HtmlWebpackPlugin来生成HTML文件,使用CleanWebpackPlugin来清空打包目录等。 在配置Plugins时,我们需要在plugins属性中指定要使用的插件。例如: ``` const HtmlWebpackPlugin = require('html-webpack-plugin') const { CleanWebpackPlugin } = require('clean-webpack-plugin') module.exports = { entry: './src/index.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js' }, module: { rules: [ // ... ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html' }), new CleanWebpackPlugin() ] } ``` 上面的代码中,我们使用了HtmlWebpackPlugin来生成HTML文件,使用CleanWebpackPlugin来清空打包目录。 四、总结 以上就是关于Webpack的介绍,当然,Webpack的配置还有很多细节需要注意,但是上面的内容已经可以让我们基本了解Webpack的使用方法和配置。如果您想要深入了解Webpack,可以查看Webpack的官方文档,里面有更详细的介绍和示例。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值