webpack — 入门详解

2,035 阅读6分钟

webpack简介:

  • webpack 是一个前端资源加载/打包的工具。 其将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源

webpack的作用:

  1. 语法转换
  • 转换Es6语法
  • less/sass转换成css
  1. html/css/js代码压缩合并
  2. webpack可以在开发期间提供一个开发环境
  • 自动打开浏览器
  • 保存时自动刷新
  1. 图片压缩
  2. 。。。

webpack的核心概念

  • Entry : 指定webpack开始构建的入口模块
  • Output : 指定webpack如何命名输出的文件以及输出的目录
  • Loader: webpack默认只能处理javascript,而loader的存在就能将一些非js文件处理成其能够处理的模块
  • Plugins:plugins的存在又扩展了webpack的功能,其功能十分强大,例如打包优化,压缩等

一. webpack初始化项目:

  1. 安装 node.js —— 要使用webpack,必须确保电脑上存在着node.js这个运行环境
  2. 安装webpack —— 在命令行输入命令 npm install webpack -g
  3. 初始化项目 npm init -y
  4. 安装依赖包 npm install webpack webpack-cli -D
  5. 到package.json文件中配置'scripts' : {"build":"webpack --config webpack.config.js"}
  6. 若后期配置了热更新,可在package.json文件中在配置'scripts' : {"dev":"webpack-dev-server --config webpack.config.js"}

二. 配置文件出入口

  • 首先创建一个文件 : webwebpack.config.js —— 这个文件就当作我们的配置文件
entry:
1. 单个entry(写法1):
    module.exports = {
        entry: './input.js'    当前入口文件叫做 input.js
    }
2. 单个entry(写法2):
    module.exports = {
        entry: {
            main: '.input.js'
        }
    };
3.多个entry
    module.exports = {
        entry : {
            hame : './home.js',
            about:'./about.js'
            other:'./other.js'  
        }
    }
output —— 出口就是webpack打包完成的输出:
1.单个entry情况下对应的output:
    module.exports = {
        entry: './src/index.js',
        output: {
            path : path.resolve(__dirname,'dist'),   //输出后存储的路径
            filename : 'output.bundle.js'           // 输出后文件的名字
        }
    };
2.多个entry情况下对应的output:
    module.exports = {
        entry : {
            hame : './home.js',
            about:'./about.js'
            other:'./other.js'  
        },  
        output: {
            path : path.resolve(_dirname,'dist'),   
            filename : '[name].bundle.js'        // name会自动替换文件名为入口的属性名
        }
    }

三. loader-常用loader:

  • Webpack自身只支持加载js和json模块,而Loader能让webpack去处理其他类型的文件
  • loader需要下载,如果不知道要下什么,可根据报错下载所需loader
url-loader - 将文件转换为base64 url的webpack加载程序,通常用于处理图片:需要在下载file-loader
module.exports = {
    module: {
        rules : [{
            test : /\.(png|jpg|gif)$/i,  //要匹配的文件
            use : [{
                loader : 'url-loader',   //使用的规则
                options : {
                    limit:8192      //文件大小限制,若文件小于此限制,转换为base64格式,若大于直接输出图片
                    name:"[name].[ext]",        //输出的文件名
                    publicPath:'../images/',    //静态资源的引用路径
                    outputPath:"images/"        //输出的文件目录
                }
            }]
        }]
    }
};
babel-loader - 把高版本的js向后(es5)兼容
 module :{
    rules:[
        //这个是url-loader
        {
            test:/\.(png|jpg|gif)$/i,
            use:[
                {
                    loader:'url-loader',
                    options:{
                        limit:8192
                    }
                }
            ]
        },
        
        //这个是babel-loader
        {
            test:/\.js$/,                                 //检测将要匹配的文件
            exclude: /(node_modules)/,     //要排除的文件
            use:{                                           //使用了什么loader
                loader : 'babel-loader',
                options:{                                   
                    presets:['@babel/preset-env']           //使用什么规则
                }
            }
        }
    ]
}
sass-loader:
module.exports = {
    module: {
        rules : [
        // sass
            {
                test: /\.s[ac]ss$/i,
                use: [
                    'style-loader',
                    'css-loader',
                    'sass-loader',
                ],
            },
        ]
    }
};

四. Plugin-常用插件:

  • Plugin和loader是两个比较混淆和模糊的概念。Loader是用来转换和加载特定类型的文件,所以loader的执行层面是单个的源文件。而plugin可以实现的功能更强大,plugin可以监听webpack处理过程中的关键事件,深度集成进webpack的编译器,可以说plugin的执行层面是整个构建过程。Plugin系统是构成webpack的主干,webpack自身也基于plugin系统搭建,webpack有丰富的内置插件和外部插件,并且允许用户自定义插件
  • 与loader不同的是,使用plugin我们必须先引用该插件
例如:
const webpack = require('webpack'); // 用于引用webpack内置插件
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 外部插件

module.exports = {
plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new HtmlWebpackPlugin({template: './input.html'})
]
};
minCssExtract:
plugins:[
    new MiniCssExtracPlugin({
        filename:'[name].css',          //name 为 entry里的名字  不是必须设置
        filename: "css/inx.css"         //或这样写
        chunkFilename: '[id].css'       //不是必须设置
    })
]

//要使用这个的时候,要在sass-loader中的use里在配置一下,将style-loader换成这个MiniCssExtracPlugin.loader
    use: [{
            loader: MiniCssExtractPlugin.loader,
            options: {
                publicPath: "../"
            }
        },
        "css-loader",
        "less-loader"
    ]
DefinePlugin:
- definePlugin允许创建可以配置的全局常量
new webpack.DefinePlugin([
    'service_url' : josn.stringify('http://www.baidu.com')   
    // service_url  为变量,这样即使改变访问的地址,也可以通过变量来控制
])
HtmlWebpackPlugin-帮助我们生成html文件
1. 系统默认生成的:
plugins: [
    new HtmlWebpackPlugin()   // 这样就能执行了-> 就会生成index.html文件,并且会自动帮我们引入js和css文件
]
2. 我们自定义的
new HtmlWebpackPlugin({
    title: 'My App',                //html的title
    filename: 'indexa.html'   //生成的文件名字
    template: 'template.html'       //自己的输入文件的内容——在创建一个template.html文件
    //就可以在template.html文件里定义title —— 在title标签里输入<%= htmlWebpackPlugin.options.title %>
    //同样也可在此文件里引用script 或 其他不需要打包的div 
})
//之后我们indexa.html里,就会出现template.html文件里定义的东西

五. DevServer-热更新:

module.exports = {
    //...
    devServer: {
        contentBase: path.join(__dirname, 'dist'),   //在哪个目录下启动该插件 ,并且此dist要与上面的output 相一致 ,可以不写
        compress: true,   //是否压缩
        port: 9000          // 启动的端口
        open: true    // 自动打开
    }
};

注:

  • 通常我们都会初始化文件 获得查看配置文件的文件。
  • npm init - y

webpack常用loader与plugins梳理

  1. 初始化项目并定义出入口, 模式 mode : development未压缩的,production 压缩的
  2. 配置开发服务器/热更新 —— 下载webpack-dev-server
  3. 配置package.json中的scripts脚本
  4. 处理css文件 ———— 下载css-loader style-loader
    • text 为要文件
    • use: 为要使用的规则 ,处理顺序从右向左
    • css-loader让webpack能够识别解析css文件;
    • style-loader让解析后的css内容,能够作用到页面中
  5. 分离css文件 —— 下载mini-css-extract-plugin 插件
  6. 处理less文件 —— 解析less文件需要识别less语法,所以除了less-loader 需要额外下载 lesss包
  7. 配置图片的加载 —— 下载url-loader和file-loader
    • url-loader 若不配置,默认会将文件转换成base64字符串的格式, 图片会转化成base64字符串了
    • 好处是浏览器不用发送请求了,直接可以读取
    • 坏处是如果图片太大,在转换 base64 格式 就会让图片体积增大30%左右,得不偿失
    • 所以需要通过options配置选项进行配置limit,可以设置一个临界值,大于这个值会将整个文件直接打包到目录中,得到是路径,若小于这个值,就会直接转换成base64,节约请求的次数
  8. 每次打包时清除dist目录 —— 下载clean-webpack-plugin插件
    • 引入时 const { CleanWebpackPlugin } = require("clean-webpack-plugin");
    • 配置图片的打包输出目录,默认是直接输出到了dist根目录,可以通过options进行设置
  9. 生产环境与开发环境分离 ———— 下载webpack-merge 注此为合并方法
    • 拆分webpack.config.js文件
    • 新建config文件夹 - 分别建三个文件 webpack.base.js 公共位置 , webpack.dev.js 开发环境配置 webpack.pro.js 生产环境配置
  10. 提取公共模块 , 多用于多入口并且引用了相同的模块
    • 在webpack.config.js文件中的module.js下配置
    • optimization:{splitChunks:{chunks:"all" //提取所有文件的公共模块}}
    • 注 : 不需要安装 内置插件
  11. webpack处理vue 下载vue-loader vue-template-compiler
    • const VueLoaderPlugin = require("vue-loader/lib/plugin")
    • webpack配置 在rules中 引入 {text :/.vue$/ ,loader:"vue-loader"} 在plugins中引入
  12. vue-cli 脚手架环境配置rem 下载lib-flexible postcss-px2rem
    • 删除index.htmll中的meta标签 lib-flexible会为页面根据屏幕自动添加meta标签 动态控制其属性
    • 在src/main.js中导入插件包, import 'lib-flexible'
    • 配置vue.config.js ,在module.exports下配置
    •   `css:{
            loaderOptions:{
                css:{},
                postcss:{
                    plugins:[
                        require('postcss-px2rem')({
                            //适配375屏幕,设计图为750时 量出来的尺寸要/2
                            remUnit:37.5
                        })
                    ]
                }
            }
        }`
      
  13. 反向代理的配置
    • webpack的反向代理,可以起一个临时的代理服务器,帮助解决在开发过程中的跨域问题,就算跨域了也能拿到后台的数据
    •   proxy:{
            //只要请求的路径以/music开头,都会被代理
            //例 : /music/list  => https://.../music/list
            "/music":{
                target:"https://.../",      //代理基础路径
                pathRewrite:{'^/music':""}  //替换, 当配置此后 https://.../list
            }
        }