webpack基础

Webpack

1. 介绍

  • 一种构建工具,静态模块打包器
  • 把前端资源文件(js、css、img、json、less)等作为模块打包成静态资源(bundle)

2. 五个核心概念

2.1 Entry(入口)

有很多个需要打包的文件,从哪个文件开始打包

入口(Entry)指示 Webpack以哪个文件为入口起点开始打包,分析构建内部依赖图。

2.2 Output(输出)

把需要打包的文件打包后弄到哪

输出(Output)指示 Webpack 打包后的资源bundles输出到哪里去,以及如何命名。

2.3. Loader

webpack只认识js,loader能帮webpack认识别的(css,img等)

Loader 让 Webpack能够去处理那些非JavaScript文件(webpack自身只理解JavaScript)

2.4. Plugins(插件)

干loader做不到的活,压缩,优化等

插件(Plugins)可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量等。

2.5. Mode(模式)

webpack用的相应配置。分为开发模式(development)和生产模式(production)

模式(Mode)指示 Webpack使用相应模式的配置。

选择描述特点
development会将process.env.NODE_ENV的值设为development。启用NamedChunksPlugin和 NamedModulesPlugin。能让代码本地调试运行的环境
production会将process.env.NODE_ENV 的值设为production.会将process.env.NODE_ENV 的值设为production.FlagIncludedChunksPlugin,ModuleConcatenationPlugin,NoEmitOnErrorsPlugin,OccurrenceOrderPlugin, SideEffectsFlagPlugin和UglifyJsPlugin.能让代码优化上线运行的环境

3. 怎么打包文件

3.1 初始化

npm init
选默认值

3.2 下包

  • -g全局安装,在任何位置 npm i webpack webpack-cli -g 安装一次就可以,在安装会替代以前的版本
  • -D本地安装,在项目根目录,npm i webpack webpack-cli -D 添加到开发依赖

3.3初体验

3.3.1 写要打包文件的代码
  • 根目录新建src(源代码目录)
  • 根目录新建build(webpack打包后)
  • 在src文件夹中新建xx.js,该文件里写js代码
//import xx from 'xx'或import 'xx' 引入需要打包的其他文件
function add(a,b){
    return a+b
}
console.log(add(1,2));
3.3.2 打包js文件

在根目录打开命令行工具
开发环境:webpack ./src/index.js -o ./build/built.js --mode=development
生产环境:webpack ./src/index.js -o ./build/built.js --mode=production
使用webpack,把./src/xx.js作为入口文件,打包到./xx/ 模式用xx

  • 可以在js中导入json文件
import a from '../data/data.json'
console.log(a);
  1. webpack能处理js/json资源,不能处理css/img等其他资源
  2. 生产环境和开发环境将ES6模块化编译成浏览器能识别的模块化~
  3. 生产环境比开发环境多一个压缩js代码。

3.5 打包样式资源

3.5.1 打包css文件
  1. src所在目录下定义配置文件webpack.config.js
const {resolve} = require('path')
module.exports={
    //webpack配置
    //入口起点
    entry:'./src/index.js',
    //输出
    output:{
        //输出文件名
        filename:'built.js',
        //输出路径
        //__dirname node.js的变量,代表当前文件的目录绝对路径
        path:resolve(__dirname,'build')
    },
    module:{
        rules:[
            //详细loader配置
            {
                test:/\.css$/,
                //使用多个loader要用use,如果是一个只需要写loader:''即可。比如loader:'url-loader'
                use:[
                    //use数组中loader执行顺序:从右到左,从上到下 依次执行
                    //创建style标签,将js中的样式资源插入进行,添加到head中生效
                    'style-loader',
                    //将css文件变成commonjs模块加载js中,里面内容是样式字符串
                    'css-loader'
                ]
            }
        ]
    },
    //plugins的配置
    plugins:[
        //详情plugins
    ],
    //模式
    mode:'development' //开发模式 
}
  1. 项目根目录下载style-loader包和css-loader包
    npm i css-loader style-loader -D
  2. 打包`webpack
3.5.2打包 less文件
  1. 在webpack.config.js的rules中添加
{
	test:/\.less$/,
	use:[
		'style-loader',
        'css-loader',
        'less-loader'
    ]
}
  1. 下less-loader包和less包
    npm i less-loader less -D
  2. index.js中引入改该less文件
  3. 打包
  4. webpack

3.6 打包html资源

  1. 下包
    npm i html-webpack-plugin -D
  2. 在webpack.config.js中引入html-webpack-plugin插件
const HtmlWebpackPlugin	=	require('html-webpack-plugin')

在plugins中添加

new HtmlWebpackPlugin({
            template: './src/index.html' //要打包的html的路径
})
  1. 打包webpack

3.7打包图片资源

  1. 下包
    npm i url-loader file-loader -D
    npm i html-loader -D

  2. 在webpack.config.js的rules中添加

//不能处理html里面的图片
{
	test:/\.(jpg|png|gif)$/,
	loader:'url-loader',
    options:{
    //图片大小小于8kb,就会被base64处理
    //优点:减少请求数量(减轻服务器压力)
    //缺点:图片体积会更大(文件请求速度更慢)
    limit: 8*1024
    }
},
//处理html中的图片
{
	//负责引入html文件的img图片(被url-loader处理)
    test: /\.html$/,
    loader: 'html-loader',
    options:{ esModule:false }
}

3.7.1 可能出现的错误及解决方法
  • 如果出现两次图片,不显示,请在loader加上type:‘javascript/auto’
    打包压缩图片后打开背景图片不显示:原因是webpack5.0像url-loader,file-loder都是废弃不会直接使用的。如果想要使用这些废弃的旧功能,加上type: javascript/auto
{
	// 匹配哪些文件,test就是代表匹配了哪些文件
    test: /\.(png|jpg)$/,
    loader: 'url-loader',// 这个还需要安装file-loader
    options: {
    // 图片转换为base64模式
    // 图片体积会变大
    limit: 8 * 1024,
    name:'[hash:10].[ext]',
    },
    type:'javascript/auto'
}
  1. 打包 webpack

3.8打包其他资源

在webpack.config.js的rules中添加

{
//除了以下资源
	exclude:/\.(css|js|html)$/, 
	loader:'file-loader'
}

4.开发服务器devServer

4.1. 下包npm i webpack-dev-server

4.2. 配置

webpack.config.js中的module.exports添加devServer

//开发服务器devServer:用来自动化(自动编译,自动打开浏览器,自动刷新浏览器)
    //特点:只会在内存中编译打包,不会有任何输出
    //启动devServer指令为:npm webpack-dev-server
    devServer:{
        contentBase:resolve(__dirname,'build'),
        compress:true,
        port:3000,
        open:true
    },

4.3. 启动devServer

指令为npx webpack-dev-server

4.4 可能出现的错误及解决方法

4.4.2 改了配置一定要重新启动

Class constructor ServeCommand cannot be invoked without ‘new’
解决:删了node_modules ,重新npm install

4.4.3 html-webpack-plugin版本问题

Cannot read property ‘tap’ of undefined
解决:“html-webpack-plugin”: “^3.2.0”

4.4.4webpack版本问题

webpack5启动
解决:npx webpack serve

我的配置为:

"devDependencies": {
    "@webpack-cli/serve": "^1.5.1",
    "css-loader": "^5.2.7",
    "file-loader": "^6.2.0",
    "html-loader": "^2.1.2",
    "html-webpack-plugin": "^5.3.2",
    "less": "^4.1.1",
    "less-loader": "^10.0.1",
    "style-loader": "^3.2.1",
    "url-loader": "^4.1.1",
    "webpack": "^5.46.0",
    "webpack-cli": "^3.3.12",
    "webpack-dev-server": "^3.11.0"
  },

5.配置开发环境

1. entry:

‘起点文件的路径’

2. output:

{

2.1 filename

:‘路径 / 输出文件名’

2.2 path

:resolve(__dirname,‘输出到哪个文件夹’)
}

3. module

:{

3.1 relues

:[
//loader配置
{
//检测需要打包的文件类型

3.1.1 test

: /.xx文件后缀名
或者

3.1.1 exclude

: /.需要排除的文件后缀名/

3.1.2 use

:[
‘用到的loader1’,
‘用到的loader2’
]
或者 只用到一个loader时

3.1.2 loader

:‘用到的loader’

3.1.3 options

:{

3.1.3.1limit

:图片大小(小于会转化base64模式),

3.1.3.2 name

:’[hash:10].[ext]’ (用哈希值前十位+后缀名命名) ,

3.1.3.3 outputPath

:‘想把该类型文件打包到哪个文件夹’
}
}
]
}

4. plugins

:[
new HtmlWebpackPlugin({
template: ‘路径/打包的html’
})
]

5. mode

:‘用什么模式(开发者|生产者)’

6. devServer

:{
contentBase:resolve(__dirname,‘要运行项目的目录’),
compress:true,(是否启动zgip压缩)
post:启用端口号
open:是否自动打开
}
结合代码参考更有效哦

//resolve用来拼接绝对路径的方法
const { resolve } = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
/* 
loader:下载,使用
plugins:下载,引用,使用 
*/
module.exports = {
    //webpack配置
    //入口起点
    entry: '/src/js/index.js',
    //输出
    output: {
        //输出文件名
        filename: 'js/built.js',
        //输出路径
        //__dirname node.js的变量,代表当前文件的目录绝对路径
        path: resolve(__dirname, 'build')
    },
    module: {
        rules: [
            //详细loader配置
            {
                test: /\.css$/,
                use: [
                    //use数组中loader执行顺序:从右到左,从上到下 依次执行
                    //创建style标签,将js中的样式资源插入进行,添加到head中生效
                    'style-loader',
                    //将css文件变成commonjs模块加载js中,里面内容是样式字符串
                    'css-loader'
                ]
            },
            {
                test: /\.less$/,
                use: [
                    'style-loader',
                    'css-loader',
                    'less-loader'
                ]
            },
            {
                // 匹配哪些文件,test就是代表匹配了哪些文件
                test: /\.(png|jpg)$/,
                loader: 'url-loader',// 这个还需要安装file-loader
                
                options: {
                    // 图片转换为base64模式
                    // 图片体积会变大
                    limit: 8 * 1024,
                    name:'[hash:10].[ext]',
                    outputPath:'imgs'
                },
                //webpack5以上
                // type:'javascript/auto'
            },
            {
                //负责引入html文件的img图片(被url-loader处理)
                test: /\.html$/,
                loader: 'html-loader',
                options:{ esModule:false }

            },
            {
                exclude:/\.(css|html|less|jpg|png|js|json)$/,
                // test: /\.ttf$/,
                loader:'file-loader',
                options:{
                    name:'[hash:10].[ext]',
                    outputPath:'media'
                }
            }
        ]
    },
    //plugins的配置 
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html'
        })
    ],
    //模式
    mode: 'development' , //开发模式 
    //开发服务器devServer:用来自动化(自动编译,自动打开浏览器,自动刷新浏览器)
    //特点:只会在内存中编译打包,不会有任何输出
    //启动devServer指令为:npm webpack-dev-server
    devServer:{
        contentBase:resolve(__dirname,'build'),
        compress:true,
        port:3000,
        open:true
    },
    
}

6.css提取成单独文件

6.1.下包

npm i mini-css-extract-plugin -D

6.2. 配置

6.2.1 在webpack.config.js中引入

const MiniCssExtractPlugin = require('mini-css-extract-plugin')

6.2.2使用loader配置

css的use里

//style-loader
 MiniCssExtractPlugin.loader,
6.2.3 plugins里添加插件
new MiniCssExtractPlugin({
           //css文件输出位置
           filename:'css/built.css'
       })
6.2.4webpack启动

6.3.可能出现的错误及解决方法

6.3.1 没有去掉style-loader

[webpack-cli] Failed to load ‘F:\web\sy\sy-webpack\webpack.config.js’ config
[webpack-cli] ReferenceError: style is not defined
解决办法://style-loader

6.3.2webpack版本问题

ERROR in [entry] [initial] css/built.css
(0 , _identifier.getUndoPath) is not a function

解决办法:把webpack换5"webpack": “^5.46.0”

7.css兼容性处理

7.1.下包

npm i postcss-loader postcss-preset-env -D

7.2.使用loader的配置

css 的use里面加

                    {
                        loader: 'postcss-loader',
                        options: {
                            ident: 'postcss',
                            plugins: () => [
                                require('postcss-preset-env')()
                            ]
                        },
                    }

7.3.设置package.josn

"browserslist": {
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ],
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ]
  },

7.4.设置node环境变量:

process.env.NODE_ENV = ‘development’

7.5.webpack启动
7.6.可能出现的错误及解决办法
7.6.1代码语法错误

ERROR in ./src/css/index.css Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js): ModuleBuildError: Module build failed (from ./node_modules/postcss-loader/dist/cjs.js): ValidationError: Invalid options object. PostCSS Loader has been initialized using an options object that does not match the API schema.

解决办法:

  1. 可能是打错代码了
  2. 将postcss-loader换成3.0.0版本
  3. 用最新语法
    https://www.npmjs.com/package/postcss-loader
{
   loader: 'postcss-loader',
   options: {
   	ident: 'postcss',
       plugins: () => [
       	require('postcss-preset-env')()
       ]
   },
}

把以上代码换成以下代码

{
	loader: "postcss-loader",
    options: {
    	postcssOptions: {
        	plugins: [
            	[
                	"postcss-preset-env",
                     {
                     	// Options
	                 },
                 ],
             ,
        },
    }
}

8.压缩css

8.1下包

npm i optimize-css-assets-webpack-plugin -D

8.2 在webpack.config.js中引入

const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')

8.3plugins中添加插件

new OptimizeCssAssetsWebpackPlugin()

8.1webpack启动

9.JS语法检查eslint

9.1. 使用loader配置

{
                test:/\.js$/,
                exclude:/node_modules/,
                loader:'eslint-loader',
                options:{
                    fix:true //自动修复
                }
}

9.2. 下包

npm i eslint-loader eslint eslint-config-airbnb-base eslint-plugin-import -D

9.3. 设置package.json

添加

 "eslintConfig":{
    "extends":"airbnb-base"
  },

9.4. 下一行eslint规则失效

写在想不检测代码的上一行
eslint-disable-next-line

10. js兼容性处理

10.1 基本js兼容性处理–>@babel/preset-env

问题:只能转换基本语法,如promise不能转换

  1. loader
{
                test:/\.js$/,
                exclude:/node_modules/,
                loader:'babel-loader',
                options:{
                    //预设 :指示babel做怎么样的兼容性处理
                    presets:['@babel/preset-env']
                }
},
  1. 下包npm i babel-loader @babel/core @babel/preset-env -D
  2. webpack

10.2 全部js兼容性处理–>@babel/polyfill

问题:我只要解决部分兼容性问题,但是将所有兼容性代码全部引入,体积太大了

  1. 下包@babel/polyfil1
  2. index.js引入
    import ‘@babel/polyfill’

10.3 需要做兼容性处理的就做:按需加载–> core-js

  1. 下包npm i core-js -D
  2. 修改loader
presets: [
                        [
                            '@babel/preset-env', {
                                useBuiltIns: 'usage',
                                corejs: {
                                    version: 3
                                },
                                targets: {
                                    chrome: '60',
                                    firefox: '60',
                                    ie: '9',
                                    safari: '10',
                                    edge: '17'
                                }
                            }
                        ]
                    ]

11.压缩html、js

  1. 把mode模式改为production

12.webpack性能优化

  • 开发环境性能优化
  • 生产环境性能优化

12.1开发环境性能优化

  • 优化打包构建速度
  • 优化代码调试

12.2生产环境性能优化

  • 优化打包构建速度
  • 优化代码运行的性能

13.HMR热模块替换

HMR: hot module replacement热模块替换/模块热替换
作用:一个模块发生变化,只会重新打包这一个模块(而不是打包所有模块)极大提升构建速度

样式文件:可以使用HMR功能:因为style-loader内部实现了~js文件:默认不能使用HMR功能
在devserver里加hot: true

js文件: 默认无该HMR功能,需要添加支持该功能的代码,
只能处理非入口js文件

html文件:默认不能使用HMR功能.同时会导致问题: html文件不能热更新了~(不用做HNR功能)
解决:修改entry入口,将html文件引入
入口文件 entry: [’./src/js/index.js’, ‘./src/index.html’]

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值