zoukankan      html  css  js  c++  java
  • webpack

    webpack 4x

    中文文档:https://www.webpackjs.com/concepts/

    网页中的静态资源

    • js : .js .jsx(react).coffee .ts(Typescript 类 c#语言)
    • css: css .less .sass(基本没用了) .scss
    • Images
    • 字体模板
    • 模板文件 : .ejs .jsde .vue

    静态资源多了有什么问题?

    1. 网页加载速度慢, 因为 我们要发起很多的二次请求;
    2. 要处理错综复杂的依赖关系

    如何解决上述两个问题

    1. 合并、压缩、精灵图、图片的Base64编码
    2. 可以使用webpack可以解决各个包之间的复杂依赖关系;

    压缩合并工具:

    • gulp是基于task任务的 (小乔,灵活,便于小项目的构建)
    • webpack 基于整个项目构造()

    简介

    webpack是前端的一个项目构建工具,它基于Node.js开发出来的一个前端工具

    注意

    es6语法浏览器无法识别,得降低版本

    能做什么?

    1. 能处理js文件的互相依赖关系
    2. 能处理js的兼容问题,把高级的、浏览器不识别的语法,转为低级的,浏览器能正常识别的语法

    安装webpack

    先全局安装

    1. 安装:npm install -g webpack
    2. 安装脚手架:npm install -g webpack-cli
    3. 也可以一次安装两个:yarn add webpack webpack-cli
    4. 检查版本号(没有版本号代表安装失败):webpack -v

    再局部安装

    1. 安装:npm install webpack -D
    2. 安装脚手架:npm install webpack-cli -D
    3. 也可以一次安装两个:yarn add webpack webpack-cli -D (-D就是--save-dev 。-S就是--save)

    动手:

    最简单的打包,使用默认0配置,啥都不配置。

    • 新建一个项目文件,yarn init -y,初始化默认包配置文件
    • 局部安装webpackyarn add webpack webpack-cli -D
    • 新建src文件夹,里边新建一个index.js,随便编写脚本文件
    • npx webpack,发现会有一个dist目录生成,里边有一个压缩过的main.js
    • 在src和dist中分别创建一个index.html引入各自的js。分别在浏览器中打开。

    知识点:

    • npx是npm v5.2引入的一个命令,npx 会自动查找当前依赖包中的可执行文件,如果找不到,就会去 PATH 里找。如果依然找不到,就会帮你安装!

    • 压缩过的js会多出很多代码,为什么?

      • 打包,默认支持js的模块化,多出来的很多东西是关于模块化的兼容
    • dist中html在浏览器中能正常输出,src中的html却会报错‘require is not defined’,为什么?

      • dist中的打包出来的代码,模块化相关的东西是经过兼容处理的,所以不会报这个错
      • src里边的代码没有引入模块化相关的js文件,所以会报错。
      • 但是在命令行中用node执行是不会报错的,因为node环境中有模块化相关的js文件

    手动配置webpack

    默认webpack的配置文件时webpack.config.js。名字是死的,

    webpack-cli/bin/config-yargs.js中搜索webpack.config.js,默认有两个名字可以用

    出口入口和模式

     
     
     
     
     
     
     
     
    let path = require('path');//模块用于处理文件与目录的路径
    module.exports = {
        mode:'development',//打包模式:开发或生产
        entry:'./src/01.js',//目标文件
        output:{
            filename:'bundle.js',//输出的名字
            path:path.resolve(__dirname,'build')//必须是绝对路径:
            //publicPath:'https://static2.yscase.com/'//把所有路径都加上cdn前缀地址
            //node的path对象的resolve方法可以把当前路径转为绝对路径
            //__dirname:当前模块的目录名
            //参考说明:http://nodejs.cn/api/path.html#path_path_resolve_paths
        }
    }
     

    自定义的配置文件名字

    如:webpack.config.my.js

    执行时,要这样执行:webpack --config webpack.config.js

    配置package.json脚本

    如果嫌弃命令语句太长,可以在package.json里添加脚本语句

     
     
     
    xxxxxxxxxx
     
     
     
     
    "scripts":{
        "build":"webpack --config webpack.config.my.js"
     },
     

    执行yarn run build

    webpack-dev-server

    启动一个服务器,在服务器上预览

    • 安装yarn add webpack-dev-server -D

    • 配置

       
       
       
      xxxxxxxxxx
       
       
       
       
      devServer:{
          progress:true,
          contentBase:'./build',//指定文件夹
          port:3000,//设置端口号
          compress:true,//压缩
      },
       
    • 添加到脚本

       
       
       
      xxxxxxxxxx
       
       
       
       
      "scripts": {
         "dev": "webpack-dev-server"
      }
       
    • 执行yarn run dev

    html打包

    html-webpack-plugin(插件)

    会自动引入js

    普通单页面

    • 安装插件yarn add html-webpack-plugin -D

    • 配置package,添加脚本

       
       
       
      xxxxxxxxxx
       
       
       
       
      "scripts": {
          "build": "webpack",
      },
       
    • 配置插件(你的第一个插件)

      • 先在顶部引入

         
         
         
        xxxxxxxxxx
         
         
         
         
        let HtmlWebpackPlugin = require('html-webpack-plugin');//打包html
         
      •  
         
         
        xxxxxxxxxx
         
         
         
         
        plugins:[
            new HtmlWebpackPlugin({
                template:'./src/index.html',//要打包的html
                filename:'index.html',//输出的文件名
                minify:{
                    removeAttributeQuotes:true,//删除双引号
                    collapseWhitespace:true,//删除换行和空格
                },
                hash:true//hash随机数,给引用文件添加版本号
            })
        ]
         
    • 压缩html

       
       
       
      xxxxxxxxxx
       
       
       
       
      new HtmlWebpackPlugin({
         minify:{
             removeAttributeQuotes:true,//删除双引号
             collapseWhitespace:true,//删除换行和空格
         },
      })
       
    • hash戳解决缓存问题

      • 给引用文件添加版本号

         
         
         
        xxxxxxxxxx
         
         
         
         
        new HtmlWebpackPlugin({  
           hash:true//hash随机数,给引用文件添加版本号
        })
         
      • 文件名添加hash

         
         
         
        xxxxxxxxxx
         
         
         
         
        output:{
           filename:'bundle.[hash:8].js',//输出的名字
        },
        //加:8代表只显示8位hash值
         
    • 执行yarn run build

    多页应用打包

    有各自的html和入口js文件

     
     
     
    xxxxxxxxxx
     
     
     
     
    const Path = require('path');
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    module.exports = {
        mode:'development',
        entry:{ //多页时,写成对象模式,起个名字
            home:'./src/index.js',
            share:'./src/share.js'
        },
        output:{
            filename:'[name].js', //此时name为入口时起的名字
            path:Path.resolve(__dirname,'dist')
        },
        plugins:[
        //HtmlWebpackPlugin插件有几个页面就实例化几个
            new HtmlWebpackPlugin({
                template:'./src/index.html',
                filename:'index.html',
                chunks:['home']//指定入口文件
            }),
            new HtmlWebpackPlugin({
                template:'./src/share.html',
                filename:'share.html',
                chunks:['share']//指定入口文件
            })
        ]
    }
     

    样式打包

    打包css,less

    打包css,less(less-loader),sass等

    • 安装依赖yarn add css-loader style-loader -D

    • webpack‘配置文件,

       
       
       
      xxxxxxxxxx
       
       
       
       
      module:{
          rules: [
              {
                  test: /.css$/,
                  use: [
                  { loader: "style-loader" },//写成对象时可以配置参数
                  "css-loader" ,//直接写字符串不能配置参数
                  ],
              }
          ],
      }
       
    • css-loader:解决@import

    • style-loader:把css内容嵌入html

    • 注意,use数组元素执行顺序是后往前,先css-loader,再style-loader

    • 如是less

       
       
       
      x
       
       
       
       
      {
          test: /.less$/,
          use: [
              "style-loader",
              "css-loader" ,
              "less-loader" ,
          ]
      }
       

    分离css

    • 安装mini-css-extract-plugin插件yarn add mini-css-extract-plugin -D

    • 是插件,就要在顶部引入

       
       
       
      xxxxxxxxxx
       
       
       
       
      let MiniCssExtractPlugin = require('mini-css-extract-plugin');//分离css
       
    • 配置插件参数

       
       
       
      xxxxxxxxxx
       
       
       
       
      new MiniCssExtractPlugin({
         //filename:'main.css',//输出的文件名
         filename:'css/main.css',//输出到指定文件夹
      })
       
    • 把原来的style-loader替换成MiniCssExtractPlugin.loader,原来的style-loader用于把css嵌入html,现在不需要了,而是,MiniCssExtractPlugin会生成一个link标签且分理处一个css文件,在html中引用

       
       
       
      xxxxxxxxxx
       
       
       
       
      {
          test: /.css$/,
          use: [
              MiniCssExtractPlugin.loader,
              "css-loader",
          ]
      },
       
    • 如是less文件的页同理

       
       
       
      xxxxxxxxxx
       
       
       
       
      {
          test: /.less$/,
          use: [
              MiniCssExtractPlugin.loader,
              "css-loader" ,
              "less-loader" ,
          ]
      }
       

    给css,less添加前缀

    postcss-loader 用来处理css优化的 autoprefixer是其中一种优化:添加浏览器前缀

    • 安装yarn add postcss-loader autoprefixer -D

    • css-loader之前执行

       
       
       
      xxxxxxxxxx
       
       
       
       
      {
          test: /.css$/,
          use: [
              MiniCssExtractPlugin.loader,
              "css-loader",
              "postcss-loader",//一定放在css-loader后面,才会先执行
          ],
      },
       
    • 如是less

       
       
       
      xxxxxxxxxx
       
       
       
       
      use: [
          MiniCssExtractPlugin.loader,
          "css-loader" ,
          "postcss-loader",//less-loader之后执行,css-loader之前执行
          "less-loader" ,
      ],
       
    • 添加postcss配置文件postcss.config.js

    •  
       
       
      xxxxxxxxxx
       
       
       
       
      module.exports = {
          plugins:[
            require('autoprefixer')
          ]
      }
       
    • 注意:请尽量在js中引入css或less,如果在css或less中引入css或less,@import导入的内容不会被自动添加浏览器前缀!

    压缩css

    把mode设置为production,webpack打包一下,会发现js会自动压缩,但css不会

    • 安装所需要的模块

    • 把mode设置为production生产模式

    • 配置文件顶部引入模块 yarn add optimize-css-assets-webpack-plugin UglifyJsPlugin -D

       
       
       
      xxxxxxxxxx
       
       
       
       
      //压缩css
      const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
      //用于压缩js,如果要压缩css就必须添加压缩js的,否则js将不会压缩,
      const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
       
    • 配置参数

       
       
       
      xxxxxxxxxx
       
       
       
       
      optimization: {
          minimizer: [
          //压缩js
              new UglifyJsPlugin({
                  cache: true,//缓存
                  parallel: true,//是否并发打包
                  sourceMap: true // 高级js 转es5会用到 source maps
              }),
              //压缩css
              new OptimizeCSSAssetsPlugin({})
          ]
      },
       
    • 执行yarn run build查看build文件夹中js和css是否都是压缩的

    图片资源打包

    file-loader

    官网https://webpack.js.org/loaders/file-loader/

    html-withimg-loader

    js中引用的图片,css中的背景图片,html中的img标签图片,

    file-loader匹配出找所有的图片,创建一个新的图片到指定目录,默认会生成新的带hash值的名字

    • 安装本地依赖yarn add file-loader -D

    • 配置loader

       
       
       
      xxxxxxxxxx
       
       
       
       
      {
          test: /.(png|jpg|gif)$/,
          use: 'file-loader'
      },
       
    • 读取图片

      • js中的图片

        • 需要通过引入(import或require),才会被打包成新的图片

           
           
           
          xxxxxxxxxx
           
           
           
           
          import girl from './girl.jpg';//引入图片
          console.log(girl);//新的图片路径
          let img = new Image();
          img.src = girl;
          document.body.appendChild(img);
           
      • css中的背景图片

        • 使用了css-loader的话,css中的背景图片都能显示正常,因为css的路径都会被转为url(require("./logo.png")),这样就会主动去生成新的路径并直接返回了
      • html中的图片

        • 默认html中的图片不会被打包,因为没有被依赖,没有通过引入(import或require)

        • 我们需要安装一个新的loader,用来解决这个问题yarn add html-withimg-loader -D

        • 在loader中添加规则

           
           
           
          xxxxxxxxxx
           
           
           
           
          {
              test: /.html$/,
              use: 'html-withimg-loader'
          },
           
    • 打包执行yarn run build

    输出到指定文件夹

     
     
     
    xxxxxxxxxx
     
     
     
     
    {
        test: /.(png|jpg|gif)$/,
        use: {
            loader:'file-loader',
            options:{
                limit:1,//小于最小体积就转为base64
                outputPath:'img/',//指定文件夹
                name:'[name]-[hash:6].[ext]',//名字
                //publicPath:'https://static2.yscase.com/'//把所有图片都加上cdn前缀地址
            }
        }
    }
     

    高级js转es5

    babel官网:https://babeljs.io/docs/en/

    配合官网文档,更细致,在打包报错时,会有报错提示,看提示是缺少什么插件(包/模块),我们就去官网上搜索,查看使用

    基本的es6

    @babel/core是babel-loader的核心,

    @babel/preset-env处理转化

    声明语句,箭头函数,class类

    babel-loader

    @babel/core

    @babel/preset-env

    • 安装yarn add babel-loader @babel/core @babel/preset-env -D

    • 添加规则

       
       
       
      xxxxxxxxxx
       
       
       
       
      {
          test: /.js$/,
          exclude: /(node_modules|bower_components)/,//匹配时排除该文件夹
          use: {
              loader: 'babel-loader',
              options: {
                  presets: ['@babel/preset-env'] //预设
              }
          }
      }
       

    class类静态属性

    plugin-proposal-class-properties

    https://babeljs.io/docs/en/next/babel-plugin-proposal-class-properties.html

    • 安装针对class类的转化 yarn add @babel/plugin-proposal-class-properties -D

    • 添加插件配置

       
       
       
      xxxxxxxxxx
       
       
       
       
          use: {
              loader: 'babel-loader',
              options: {
                  presets: [
                      '@babel/preset-env'
                  ],
                  plugins:[
                      '@babel/plugin-proposal-class-properties' //针对class
                  ]
              }
      }
       
    • 执行yarn run build

    装饰器

    plugin-proposal-decorators

    • 安装依赖yarn add @babel/plugin-proposal-decorators -D

    • 用法:https://babeljs.io/docs/en/babel-plugin-proposal-decorators注意babel插件plugins顺序

       
       
       
      xxxxxxxxxx
       
       
       
       
      options: {
          presets: [
              '@babel/preset-env'
          ],
          plugins:[
              ["@babel/plugin-proposal-decorators", { "legacy": true }],//宽松模式
              ["@babel/plugin-proposal-class-properties", { "loose" : true }]
          ]
      }
       

    transform-runtime

    如果你用了generator函数,打包时没有报错,但是打包后的代码在浏览器中却是报了错regeneratorRuntime is not defined

    此时你还需要安装@babel/plugin-transform-runtime,帮助转化的包

    plugin-transform-runtime还可以优化代码,减少重复的代码

    • 安装开发时的依赖yarn add @babel/plugin-transform-runtime -D

    • 安装生产上线时的依赖yarn add @babel/runtime -S

    • 添加到babel依赖插件中

       
       
       
      xxxxxxxxxx
       
       
       
       
      plugins:[
          ["@babel/plugin-proposal-decorators", { "legacy": true }],//宽松模式
          ["@babel/plugin-proposal-class-properties", { "loose" : true }],
          "@babel/plugin-transform-runtime"
      ]
       
    • 执行打包yarn run build

    更高级的语法

    This means you can use new built-ins like Promise or WeakMap, static methods like Array.from or Object.assign, instance methods like Array.prototype.includes, and generator functions (provided you use the regenerator plugin).

    源自babel官网: https://babeljs.io/docs/en/babel-polyfill#docsNav

    @babel/polyfill

    • 安装生产上线时的依赖yarn add @babel/polyfill -S

    • js入口顶部引入

      • require("@babel/polyfill");
      • import "@babel/polyfill";
    • 执行打包,打包后的页面在ie中也能正常执行,没有使用这款插件的在低版本浏览器会报错的

    ESLint高级js语法检验

    官网:https://eslint.org/

    暴露全局变量

    require引入的是在当前模块,并不是全局,如要暴露给全局,如下

    expose-loader

    expose-loader暴露给全局(目前juqery已经是全局的了,再次只是比如)

    • 安装expose-loader yarn add expose-loader -D

    • 使用

      • 引入时设置变量import $ from 'expose-loader?$!jquery'

      • webpack配置添加匹配规则

        {
            test:require.resolve('jquery'),
            //详解见http://nodejs.cn/api/modules.html#modules_require
            use:[{
                loader:'expose-loader',
                options:'$'//暴露出来的全局变量
            }]
        },
        
    • 打包运行

    ProvidePlugin

    ProvidePlugin在每个js模块中引入插件

    • 先引入const Webpack = require('webpack')

    • 再配置插件

      new Webpack.ProvidePlugin({
          $:'jquery',
          jquery:'juqery'
      })
      
    • 打包运行

    webpack常用配置

    sourcemap源码映射

    打包后的代码都被压缩了,浏览器上不好找到报错的地方,我们可以通过sourcemap找到报错的地方行和列

    官网文档:https://webpack.js.org/configuration/devtool/#devtool

    module.exports = {
        mode:'production',
        //源码映射,会单独生成一个sourcemap文件,浏览器调试时出错会标识列和行
        devtool:'source-map',
        //源码映射,不会产生单独的文件,但是浏览器调试时可以显示行和列
        devtool:'eval-source-map',
        // 不会产生列,但是是一个单独的映射文件
        devtool:'cheap-module-source-map',
    }
    

    watch

    实时打包更新

    
    

    常用插件

    cleanWebpackPlugin

    打包前清空文件夹https://www.npmjs.com/package/clean-webpack-plugin

    • 先安装yarn add clean-webpack-plugin -D

    • 引入插件

      const CleanWebpackPlugin = require('clean-webpack-plugin');
      
    • plugins:[
          new CleanWebpackPlugin('./dist')//传入要清空的文件夹,也可以是数组
      ],
      

    copyWebpackPlugin

    复制文件到指定目录

    • 先安装yarn add copy-webpack-plugin -D

    • 引入插件

      const CopyWebpackPlugin = require('copy-webpack-plugin');
      
    • plugins:[
          new CopyWebpackPlugin([
              {from:'./other',to:'./other'}//从根目录到输出目录
          ])
      ],
      

    bannerPlugin 内置

    给打包后的文件顶部嵌入标识语句,

    • webpack内置插件,引入webpack即可

      const Webpack = require('webpack');
      
    • new Webpack.BannerPlugin({
         banner:'2019.2.13by xiaoyue'//指定内嵌语句
      })
      

    跨域问题

    奔跑的蜗牛
  • 相关阅读:
    Linux常用快捷键
    如何Oracle 数据库备份与恢复
    Linux常用命令解释
    转摘:商业智能BI的演绎型需求和归纳型需求BI三维框架之内容维研究
    PHP中const的使用
    PHP中define的使用
    Apache配置正向代理与反向代理
    正向代理
    JAVA System.getProperty()参数
    PHP查找当前URL文件扩展名
  • 原文地址:https://www.cnblogs.com/xiaoyue-/p/10608761.html
Copyright © 2011-2022 走看看