• webpack核心概念(系列二)


    Enter与Output基础配置

    需求一;我们需要将打包后输出两个js文件

    module.exports = {
        mode: 'development',
        entry: {
            main: './src/index.js',
            sub: './src/index.js'
        },

    entry可以接收一个对象,属性main和sub表示打包后的js的名字

        output: {
            
            filename: '[name].js',
            path: path.resolve(__dirname, 'dist')
        }

    而output则要接收打包后的名字,用[name].js模糊匹配接收,此时在打包后的dist文件夹有main.js,sub.js两个文件,而且html会自动引入这两个js文件

    需求二,如果我们打包后的静态资源js文件需要放入到cdn中,可在output配置,那么在html引入的就是cnd的资源了,不是本地资源了

        output: {
            publicPath: 'http://cdn.com.cn',
            filename: '[name].js',
            path: path.resolve(__dirname, 'dist')
        }

    devtool

    devtool 配置控制 source-map 的生成 , 可以将压缩/编译文件中的代码映射回源文件中的原始位置,如果js代码有问题,可以及时定位源文件的错误,便于调试代码

    详细配置官网地址 https://www.webpackjs.com/configuration/devtool/

    配置 webpack.config.js

    module.exports = {
        mode: 'development',
        // development devtool: 'cheap-module-eval-source-map',
        // production devtool: 'cheap-module-source-map',
        devtool: 'cheap-module-eval-source-map',

    推荐使用:

    • 开发环境: cheap-module-eval-source-map     提示多,且打包性能快

    • 生产环境: cheap-module-source-map

       

    devtool其他策略详解

    sourcemap配置, 是个构建映射关系,定位源文件js文件的错误

    source-map,在打包dist文件自动生成main.map.js,精确到那一行那一列,耗费打包性能,
    inline-source-map, main.map.js在main.js中引入了,精确到那一行那一列,耗费性能,
    cheap-inline-source-map,精确到行,增加了一点性能
    cheap-module-inline-source-map,处理js业务逻辑出错,也处理第三个方插件的出错
    eval,  打包速度快,但是提示并不全面

    自动编译打包运行

    前端自动开启服务,自动打开浏览器编译,源代码发生变化,浏览器自动刷新,可以使用 webpack-dev-server 自动打包运行

    不会自动打包dist文件,因为源码在内存使用了,高效便捷.  vue-cli脚手架都内置了devServer

    1. 安装 loader

      > npm install webpack-dev-server --save-dev
    2. 详细配置见官网 https://www.webpackjs.com/configuration/dev-server/

    3. 修改 webpack.config.js

      .
      .
      .
      module.exports = {
          .
          output: {
              path: resolve(__dirname, 'build'),
              filename: 'js/app.js',
              //1. 添加 devServer 服务后需要调整输出的路径
              publicPath: '/'
          },
          module: {
              rules: [
                  .
                  .
                  .
                  {
                      test: /.(png|jpg|gif)$/,
                      use: {
                          loader: 'url-loader',
                          options: {
                              limit: 8192,                    
                              outputPath: 'images',           
                              name: '[hash:8].[ext]',       
                              //2. 删除 publicPath 配置
                          }
                      }
                  },
                  
      ​
              ]
          },
          .
          .
          //3. 增加 devServer 配置
          devServer: {
              open: true,     // 自动打开浏览器
              compress: true, // 启动gzip压缩
              port: 3000,     // 端口号
          },
          mode: 'development'
      }

    4. 配置 package.json 中 scripts 指令。增加 server 配置
     
     
     ```json
       {
          .
          .
          .
          "scripts": {
               "server": "webpack-dev-server" 
           },
          .
          .
          .
        }
    1. 运行指令 npm  run  server

    热模替换功能

    热更新、
    自动刷新,整个网页全部刷新,速度变慢,页面状态丢失
    热更新,新代码生效,网页不刷新,页面状态不丢失

    模块热替换 (HMR - Hot Module Replacement) 功能会在应用程序运行过程中替换、添加或删除模块,而无需重新加载整个页面(比如样式修改,不需刷新页面,直接替换样式即可),详细配置地址(https://www.webpackjs.com/guides/hot-module-replacement/),vue-cli也内置了该功能

    修改 webpack.config.js 的 devServer 配置,以及新增new webpack.HotModuleReplacementPlugin()内置插件

    修改配置后,需要重启服务

    const webpack = require('webpack');
        devServer: {
            
            open: true,
            port: 8080,
            hot: true,   //开启热模块跟新
            hotOnly: true
        },
        module: {
            rules: [{
                test: /.(jpg|png|gif)$/,
                use: {
                    loader: 'url-loader',
                    options: {
                        name: '[name]_[hash].[ext]',
                        outputPath: 'images/',
                        limit: 10240
                    }
                } 
            }, {
                test: /.(eot|ttf|svg)$/,
                use: {
                    loader: 'file-loader'
                } 
            }, {
                test: /.scss$/,
                use: [
                    'style-loader', 
                    {
                        loader: 'css-loader',
                        options: {
                            importLoaders: 2
                        }
                    },
                    'sass-loader',
                    'postcss-loader'
                ]
            }, {
                test: /.css$/,
                use: [
                    'style-loader',
                    'css-loader',
                    'postcss-loader'
                ]
            }]
        },
        plugins: [
            new HtmlWebpackPlugin({
                template: 'src/index.html'
            }), 
            new CleanWebpackPlugin(['dist']),
            new webpack.HotModuleReplacementPlugin()
        ],

     

    利用Babela将JS 语法转换

    借助 Babel 可以将浏览器不能识别的新语法(ES6, ES7)转换成原来识别的旧语法(ES5),浏览器兼容性处理

    1. 安装loader

      > npm install babel-loader @babel/core @babel/preset-env --save-dev

      @babel/core 是 babel 的核心库

      @babel/preset-env 是 babel 的预设的工具包,默认可以将所有最新的语法转为为 ES5

      babel-loader 是 babel 在 webpack 中的 loader 包

    2. 配置loader

      module: {
        rules: [
          .
          .
          .
          {
            test: /.js$/,
            exclude: /node_modules/,
            use: {
              loader: "babel-loader",
              options: {
                presets: ['@babel/preset-env']
              }
            }
          }
      ]
      }

    决 babel 只能转换语法的问题(如:let/const/解构赋值...),但是对Pormise,数组方法,babel解决不了,引入polyfill可以转换高级语法(如:Promise...),处理低级浏览器兼容性

    利用polyfill进行JS 兼容性处理,babel7.4版本不支持babel-polyfill,需要用到core.js代替,具体配置;https://www.cnblogs.com/fsg6/p/14496390.html

    Polyfill 是一块代码(通常是 Web 上的 JavaScript),用来为旧浏览器ie提供它没有原生支持的较新的功能

    1. 安装 polyfill

      > npm install @babel/polyfill
    2. app.js(入口文件)引入

      import '@babel/polyfill';(现在可以不用引入了,useBuiltInsL:'usage'内部自动会引入)

    解决 babel 只能转换语法的问题(如:let/const/解构赋值...),引入polyfill可以转换高级语法(如:Promise...)

    此时因为polyfill要兼容低级浏览器,打包后容量不可避免要增多,因为他要转换更高级的js语法,都是全部转换,但是我们可以实现一个按需处理转换高级语法(自动识别代码中使用的高级语法)新增useBuiltIns属性

    重新修改babel-loader的options

    { 
                test: /.js$/, 
                exclude: /node_modules/, 
                loader: 'babel-loader',
                options:{
                    present:[['@babel/preset-env',{useBuiltInsL:'usage'}]]
                }
            }

    全部编译转换高级语法打包文件大小

    按需编译转换高级语法后打包文件大小

    此时打包容量大大减少

    如果webpack.config.js中 babel-loader的options配置太多,我们可以单独新增.babelrc文件,options项放入这个文件

    webapck.coonfig.js, banel-loader删除options项

    { 
                test: /.js$/, 
                exclude: /node_modules/, 
                loader: 'babel-loader',
            }

    .babelrc文件

    {
        presets: [
            [
                "@babel/preset-env", {
                    targets: {
                        chrome: "67", //处理chrom67版本的es6语法转换,以上的chrome浏览器自己内置转换了
                    },
                    useBuiltIns: 'usage'
                }
            ],
            "@babel/preset-react"
        ]
    }
  • 相关阅读:
    深入RESTful无状态原则
    基于Tomcat7、Java、WebSocket的服务器推送聊天室
    java.lang.NoSuchMethodException: org.apache.catalina.deploy.WebXml addServlet
    POI操作Excel常用方法总结
    第章 子例程引用与闭包
    集团企业数据信息系统建设方案
    集团企业数据信息系统建设方案
    不是更快更强,而是更加自如——2015年终总结
    RESTful_基础知识
    RESTful_基础知识
  • 原文地址:https://www.cnblogs.com/fsg6/p/14489407.html
Copyright © 2020-2023  润新知