美文网首页Vue
webpack看这一篇就够了

webpack看这一篇就够了

作者: learninginto | 来源:发表于2019-12-31 00:22 被阅读0次

    webpack看这一篇就够了

    一、什么webpack?

    简单来说,就是一个前端的打包工具。

    在webpack看来,万事万物皆JS;图片是JS,css是JS……

    官方网站链接

    webpack.jpg
    • 对比gulp与webpack

    相比自动化工具gulp而言,webpack的侧重点不同。

    gulp侧重于前端开发的整个过程的控制管理,像是一条流水线,整个产品从无到有,都要受它的管控。

    而webpack更侧重于模块打包,像一个模块打包机,把开发中的所有资源(图片、js文件、css文件等)都可以看成模块,将浏览器不识别的文件(scss/ts/vue等),通过loader(加载器)和plugins(插件)对资源进行处理,打包为一个或多个模块。

    • 常用的模块化开放方案
    • 前端:
      • requirejs——AMD,依赖前置,准备工作全部做完开始执行,用define定义模块,用require调用模块,在html中调用js文件用data-main属性。AMD不支持返回函数,只能导出对象,是异步的。
      • seajs——CMD,依赖就近,后期requireJS也支持了CMD规范,所以CMD渐渐不用了。
      • ES6:moudle(export import)——ECMA,用export或者export default导出,用import导入。这种方法最简单快捷,可以利用webpack中的babel转成es5的。
    • 服务端
      • commonJS——用module.exports将模块导出,可以导出对象、函数、ES5类,但是不能导出ES6类,用require导入模块。是同步的。
    • 模块化方式的优点
    1. 解决文件之间的以来关系。
    2. 避免命名冲突、解决全局变量级全局函数泛用的现象。
    3. 解决代码的服用性。
    4. 更好的分离,按需加载。

    通常来讲,在webpack中会区分几个不同的环境进行打包:

    • 开发环境:src

    • 测试环境:test

      • 压力测试

      • 灰度测试

        ……

    • 生产环境:dist

    二、简单总结常用的功能

    1. 初始化项目,生成package.json
    npm init -y
    
    1. 安装 webpack和webpack-cli
    cnpm install webpack webpack-cli -D
    

    注:-D : --save-dev , 当前依赖要安装到开发环境中 devDependencies

    ​ -S : --save , 当前依赖要安装到生产环境中 Dependencies

    1. 创建src文件夹(开发环境的目录)

    src文件夹中必须要有一个入口文件,eg:main.js

    1. 创建webpack.config.js文件

    因为webpack在执行的时,默认会到跟目录下面的webpack.config.js(相当于gulpfile.js)文件

    1. webpack.config.js文件的配置项

      process.env查看环境变量,环境变量NODE_ENV未设置时,默认为undefined

      const path = require("path");
      
      // 配置入口文件和出口文件地址
      const PATH = {
          app:path.join(__dirname,".//src/main.js"),//路径拼接
          build:path.join(__dirname,"../dist")
      }
      
      // 配置webpack
      module.exports = {
          // 入口的配置
          entry:{
              name:PATH.app
          },
          // 出口配置
          output:{
              path:PATH.build,
              //filename:"[name].js"
              //name名与entry中的一致
               //判断当前是开发环境还是生产环境,
              filename: process.env.NODE_ENV == "development" ? "js/[name].[hash:8].js" : "js/[name].js"
          }
      }
      
    2. 打包命令(初级、基本使用)

    npx webpack  
    

    npx: 默认从当前文件的node_modules中找到相对应的模块

    打包后生成的文件.jpg
    1. scripts中的命令运行

      • 将webpack.config.js中的配置,拆分到config中

      eg: base.config.js——对应开发与生产环境

      ​ dev.config.js——对应开发环境

      ​ pro.config.js——对应生产环境

      执行命令:

      npx webpack --config config/base.config.js
      
      config.png
      • 在package.json中添加配置项
       "scripts": {
          "dev": "webpack-dev-server --progress --config config/dev.config.js",
          "build": "webpack --progress --config config/pro.config.js"
        }
      

      经过上面的简化配置,运行时只需要输入npm run build就可以了

      注:--config:指定文件的配置 --progress为显示加载进度

    2. plugins:常用的插件

    webpack中凡是用插件的地方都必须要在plugins中进行使用

    • html-webpack-plugin——打包引入js后的html文件(需要依赖webpack-cli,所以提前安装了webpack-cli)

      cnpm install html-webpack-plugin -D 
      
    • clean-webpack-plugin——打包时,清空上一次打包的内容

      cnpm install clean-webpack-plugin -D
      
    • copy-webpack-plugin——将开发环境的静态资源(img/css)拷贝到dist目录下

      cnpm install copy-webpack-plugin -D
      
    • extract-text-webpack-plugin——抽离css 优化

      cnpm install extract-text-webpack-plugin@next -D
      
    • 安装 vue-loadervue-template-compiler处理单文件组件

      cnpm install -D vue-loader vue-template-compiler
      
    • base.config.js添加配置

    const HtmlWebpackPlugin = require("html-webpack-plugin");
    const { CleanWebpackPlugin } = require("clean-webpack-plugin");
    const CopyWebpackPlugin = require("copy-webpack-plugin");
    const VueLoaderPlugin = require('vue-loader/lib/plugin');
     plugins: [
            new CleanWebpackPlugin(),
            new HtmlWebpackPlugin({
                template: "./public/index.html",
                filename: "index.html",
                //添加小图标
                favicon:"./favicon.ico"
            }),
            new CopyWebpackPlugin([
                {
                    context: path.join(__dirname, "../public"),
                    from: "**/*",
                    to: path.join(__dirname, "../dist"),
                    //忽略文件
                    ignore: ["index.html"]
                }
            ]),
           //将定义过的其它规则复制并应用到 .vue 文件里相应语言的块。
            new VueLoaderPlugin()
        ],
    
    1. loader:模块的转换

    转换浏览器不识别的文件配置项时,要在module中配置;

    • 处理vue的loader

      • 在rules中添加配置项
      {
          test: /\.vue$/,
          use: ['vue-loader']
      }
      
    • 处理JS的loader

      • babel-loader
      • @babel/core
      • @babel/preset-env
      cnpm install babel-loader @babel/core @babel/preset-env -D
      

      安装之前需要package.json同级目录下创建.babelrc文件,进行如下配置

      {
          "presets": [
              [
                  //低版本的转换 ES6 => ES5
                  "@babel/preset-env",
                  {
                      //设置浏览器版本
                      "targets":{
                          //兼容到所有浏览的最后2个版本
                          "browsers":["last 2 version"]
                      }
                  }
            ]
          ]
      }
      
      • base.config.js添加以下配置
       {
           test: /\.js$/,
           loader: "babel-loader"
       },
      
      • 在单页面开发中如果用async await不识别时,需要安装以下依赖:
      regeneratorRuntime.png
      cnpm i @babel/plugin-transform-runtime --save-dev
      cnpm i @babel/runtime --save
      

      在.bablerc文件中添加配置"plugins":["@babel/plugin-transform-runtime"]

      {
          "presets": [
              [
                  "@babel/preset-env",
                  {
                      "targets": {
                          "browsers": ["last 2 version"]
                      }
                  }
              ]
          ],
          "plugins": ["@babel/plugin-transform-runtime"]
      }
      
    • 处理css的loader

      • style-loader
      • css-loader
      • sass-loader
      • postcss-loader
      • autoprefixer

      在解析sass的时候除了需要sass-loader之外,还需要一个特别重要的模块node-sass

      注:autoprefixer 解析CSS文件,自动添加css样式的浏览器前缀到CSS内容里

      cnpm install style-loader css-loader sass-loader node-sass postcss-loader autoprefixer -D
      
    • dev.config.js添加配置 ,做CSS的抽离

      rules: [
          {
              test: /\.(css|scss)$/,
              use: ["style-loader", "css-loader", "sass-loader"]
          }
      ]
      
    • pro.config.js添加配置——见文章第五点

    • 处理图片的loader

      • url-loader

      • file-loader

      • url-loader file-loader的区别

      url-loader一般用来解析体积较小的图片,可以通过options中的limit来设置图片的大小
      如果图片大于limit的大小,则用file-loader进行解析,file-loader一般用来解析比较大的图片

      cnpm install url-loader file-loader -D
      
      • base.config.js添加配置
      {
          test: /\.(jpg|gif|png|svg)$/,
          use: {
              loader: "url-loader",
              options: {
                  limit: 2048,
                  // name是图片原始的名称  ext是文件的后缀名
                  name: "img/[name].[ext]"
              }
        }
      },
      
    • base.config.js中对字体的配置

      {
          test: /\.(woff|woff2|svg|ttf|eot)$/,
              use: {
                  loader: "url-loader",
                      options: {
                          name: "font/[name].[ext]"
                      }
              }
      },
      
    1. webpack-merge合并webpack配置项

    配置文件被分成了许多不同的部分,那么必须以某种方式来组合他们,通常就是合并数组和对象,webpack-merge很好的做到了这一点。

    cnpm install webpack-merge -D
    

    webpack-merge做了两件事:它允许连接数组并合并对象,而不是覆盖组合。

    1. webpack-dev-server 创建开发环境的服务
    cnpm install webpack-dev-server -D
    
    1. 处理非模块化的插件
    cnpm install script-loader exports-loader -D
    
    • 在base.config.js中的rules引入
    {
        //引入非模块化的插件
        test: require.resolve('zepto'),
        //转化成模块的方式
        loader: 'exports-loader?window.Zepto!script-loader'
    }
    

    三、base.config.js

    const path = require("path");
    const HtmlWebpackPlugin = require("html-webpack-plugin");
    const { CleanWebpackPlugin } = require("clean-webpack-plugin");
    const CopyWebpackPlugin = require("copy-webpack-plugin");
    
    /*
        __dirname:当前文件的绝对路径
        path.join:做路径的拼接
    */
    
    //配置入口文件和出口文件地址
    const PATH = {
        app: path.join(__dirname, "../src/main.js"),//路径拼接
        build: path.join(__dirname, "../dist")
    }
    
    //配置webpack
    module.exports = {
        //入口的配置
        entry: {
            app: PATH.app
        },
        //出口配置
        output: {
            path: PATH.build,
            filename: "[name].js"//name名与entry中的一致
        },
        //使用插件配置项
        plugins: [
            new HtmlWebpackPlugin({
                template: "./public/index.html",//基于当前根目录下寻找
                filename: "index.html",//打包完成后生成的文件名
                hash:true,//为引入js的地址添加后缀,用于清楚缓存
                inject:true,//true(默认)/body/head,是否讲js文件嵌入到html中。可以制定添加到body或head后面
                //chunks:["入口属性名"],//指定打包的文件
                //excludeChunkds:["my"],//打包除了入口属性为my的文件
                title: "M站开发",//在html中title标签中设置<%= htmlWebpackPlugin.options.title%>
                minify:{
                    removeComments:true,//清除注释
                    removeAttributeQuotes:true,//清除双引号
                    collapseWhitespace:true,//进行折叠,并且去除空格
                }
            }),
            new CleanWebpackPlugin(),
            new CopyWebpackPlugin([
                {
                    // 指定拷贝文件的目录
                    context: path.join(__dirname, "../public"),
                    from: "**/*",
                    to: path.join(__dirname, "../dist"),
                    //忽略文件
                    ignore: ["index.html"]
                }
            ])
        ],
        //别名的配置项
        resolve: {
            //文件引入的优先级,从左到右,没找到vue时会去找js,scss,art……
            extensions: [".vue",".js", "scss", "art", "css", "json"],
            //别名的配置
            alias: {
                "@": path.join(__dirname, "../src")
            }
        },
        //loader的配置 转换浏览器不识别的文件配置项
        module: {
            //规则
            rules: [
                {
                    //引入非模块化的插件
                    test: require.resolve('zepto'),
                    //转化成模块的方式
                    loader: 'exports-loader?window.Zepto!script-loader'
                },
                //一个对象代表一个规则
                {
                    test: /\.js$/,
                    loader: "babel-loader",
                    exclude: path.join(__dirname, "../node_modules")
                },
                {
                    test: /\.art$/,
                    loader: "art-template-loader"
                },
                //处理图片的loader
                {
                    test: /\.(png|jpg|gif|svg)$/,
                    use: {
                        loader: "url-loader",
                        options: {
                            limit: 2048,
                            // name是图片原始的名称  ext是文件的后缀名
                            name: "img/[name].[ext]"
                        }
                    },
                    exclude: path.join(__dirname, "../node_modules")
                },
                //处理字体的配置项(包括iconfont字体库)
                {
                    test: /\.(woff|woff2|svg|ttf|eot)$/,
                    use: {
                        loader: "url-loader",
                        options: {
                            name: "font/[name].[ext]"
                        }
                    },
                    exclude: path.join(__dirname, "../node_modules")
                }
            ]
        }
    }
    
    

    四、开发环境dev.config.js

    • dev.config.js
    const baseConfig = require("./base.config");
    const webpackMerge = require("webpack-merge");
    const path = require("path");
    
    //合并
    const config = webpackMerge(baseConfig,{
        //当前的环境
        mode:"development",
        module:{
            rules:[
                {
                    test:/\.(css|scss)$/,
                    //cssloader的执行顺序 从右到左 从下到上
                    use:["style-loader","css-loader","sass-loader"],
                    exclude:path.join(__dirname,"../node_modules")
                }
            ]
        },
        //服务器的配置项
        devServer:{
            //自动打开浏览器
            open:true,
            //设置端口号
            port:9000
        }
    })
    
    module.exports = config;
    

    五、生产环境pro.config.js

    • 使用postcss时,要在package.json同级目录下创建postcss.config.js文件
    module.exports = {
        plugins: [
            //自动添加浏览器前缀
            require("autoprefixer")({
                overrideBrowserslist: [
                    "defaults",
                    "Android 4.1",
                    "iOS 7.1",
                    "Chrome>31",
                    "ff>31",//火狐
                    "ie>=8",
                    "last 2 versions",
                    ">0%"
                ]
            })
        ]
    }
    
    • pro.config.js
    const path = require("path");
    const baseConfig = require("./base.config");
    const webpackMerge = require("webpack-merge");
    const ExtractTextWebpackplugin = require("extract-text-webpack-plugin");
    const config = webpackMerge(baseConfig, {
        mode: "production",
        module: {
            rules: [
                {
                    test: /\.(css|scss)$/,
                    //css抽离
                    use: ExtractTextWebpackplugin.extract({
                        //解析css、sass,postcss用来加浏览器的前缀
                        use: ["css-loader", "postcss-loader", "sass-loader"],
                        fallback: "style-loader",
                    }),
                    exclude: path.join(__dirname, "../node_modules")
                }
            ]
        },
        plugins: [
            new ExtractTextWebpackplugin({
                filename: "css/[name].[hash:8].css"//取打包后,哈希值的后8位
            })
        ]
    })
    
    module.exports = config;
    

    相关文章

      网友评论

        本文标题:webpack看这一篇就够了

        本文链接:https://www.haomeiwen.com/subject/rqvvoctx.html