• webpack4系列之 【1. webpack入门】


    一.为什么要学习webpack

    现在的前端网页功能丰富,特别是SPA(single page web application 单页应用)技术流行后,JavaScript的复杂度增加和需要一大堆依赖包,还需要解决SCSS,Less……新增样式的扩展写法的编译工作。所以现代化的前端已经完全依赖于WebPack的辅助了。

    现在最流行的三个前端框架,可以说和webpack已经紧密相连

    React.js+WebPack

    Vue.js+WebPack

    AngluarJS+WebPack

    可以看出,无论前端走哪条线,都要有很强的Webpack知识

    二. webpack是什么

    其实说白了,webpack就是模块打包机。

    webpack看来,一切皆模块。Webpack所做的事情就是:分析项目结构,找到js模块以及其他一些浏览器不能直接运行的语言,sass typeScript等,将其转换打包成合适的格式。共浏览器使用。在3.0以后,webpack还有了优化项目的功能

    第一点:打包webpack多个js文件打包成一个文件。减少服务器压力和下载带宽。减少请求次数和压缩js css img(对原始图片进行压缩处理、调整图片的分辨率和尺寸;服务器开启Gzip压缩功能压缩页面文本)

    第二点:转换,能够把less,scss等扩展性语言,以及各种类型的js文件都转换成标准的能被浏览器识别的语言

    第三点:优化Webpack3.0以后,担任着优化和提升性能的责任(比如第三方类库的分离,提取公共代码等)

    总结起来,就是打包/转换/优化。话不多说,我们一起来看下怎么使用webpack。如果有不当的地方,欢迎大家纠正,一起学习。

    三. webpack基础应用

    1.安装

    webpack安装的两种方式

      1. 全局安装:npm  install -g webpack

      2.本地安装: npm install --save-dev webpack(@version)

    webpack 版本查看 :webpack -v

    全局安装就是安装到全局目录下(通过 npm config set prefix “目录路径” 来设置。通过 npm config get prefix 来获取当前设置的目录

    但是对于大多数项目我们推荐安装到本地,原因是可防止不同项目依赖不同版本的 Webpack 而导致冲突。

    安装好之后,我们就可以在项目进行webpack的配置了

    2. webpack基本配置-webpack.config.js

    module.exports={

           entry:{},  // 入口文件的配置项

           output:{}, // 出口文件的配置项

           module:{}, // 模块:例如解读CSS,图片如何转换,压缩

           plugins:[],  // 插件,用于生产模版和各项功能

           devServer:{}  // 配置webpack开发服务功能

    }

    单入口:

    module.exports={

           entry:{

        entry1: './src/entry.js

           },  

           output: {
         path: path.resolve(__dirname, 'dist'),

            filename: ‘bundle.js'
           }

    }

    多入口:

    output.path对应一个绝对路径,path.resolve主要是用于设置绝对路径,并且输出文件夹建议是要使用绝对路径的.

    module.exports={

           entry1:{

                        entry1: './src/entry.js',  

                         entry2: './src/entry.js

            },  

          output: {

                      path: path.resolve(__dirname, 'dist'),

                      filename: ‘[name].js

          },

           ……

    }

    3. 所见即所得之热更新-- devServer

    devServer: {
        //设置基本目录结构,使用绝对目录
        contentBase:path.resolve(__dirname,‘dist’),
        //服务器的IP地址,可以使用IP也可以使用localhost
        host:‘localhost’,
        //服务端压缩是否开启(自行学习)
        compress:true,
        //配置服务端口号
        port:1717
    }

     

    npm run server  启动后,它是有一种监控机制的(也叫watch)。它可以监控到我们修改源码,并立即在浏览器里给我们更新。

    Webpack打包之后,运行npm run server 发现只有js 但是可以说明我们的js打包成功了,但是没有html,新建html,并且将html打包址dist文件夹。这需要借助于一个插件html-webpack-plugin

    4. Html打包-- html-webpack-plugin

    安装:npm install --save-dev html-webpack-plugin

    使用:

    const htmlPlugin = require('html-webpack-plugin')

    plugins: [
     new htmlPlugin({
            minify: { removeAttributeQuotes: true },
            hash: true,
            template: './src/index.html'
        })
    ],

     

    借助于插件-- html-webpack-plugin,可以将我们的html打包址dist文件夹,在使用之前我们需要先npm安装

    1.require引入插件

    2.因为它是一款插件所以我们需要在plugins中进行这个插件的相关配置。

    在配置的时候,需要new一个对象,传入一些参数,minify:对html文件进行压缩,removeAttributeQuotes去掉属性的双引号,hash为true是在js后面增加一段hash值,主要是为了避免浏览器缓存的,template打包的模版文件

    执行webpack,查看发现script有后缀,并且属性双引号去掉了。

    通过这个插件我们不仅能将html文件打包到dist文件夹还能压缩html,那么我们的js文件怎么压缩呢?

    5. Js压缩--uglifyjs-webpack-plugin

    如果没有webpack或gulp的话,可能我们还需要找一个压缩软件或者在线进行压缩,而在webpack中使用默认已经集成的uglifyjs-webpack-plugin插件轻松实现js代码的压缩,由于已经集成,不需要再次安装。用法:

    const uglify = require('uglifyjs-webpack-plugin'); 

    plugins:[

            new uglify()

     ],

    执行webpack打包,npm run server发现报错了,为什么呢?这就涉及到了生产环境和开发环境的区别

    因为我们在开发环境是不需要压缩js的,但是在生产环境中需要,所以uglifyjs适用于生产环境下的,

    所以如果我们在开发环境中做了生产环境做的事情,就会报错了

     

    6. Css文件打包-- style-loader,css-loader

    安装:npm install --save-dev css-loader style-loader

    使用:

          module:{       

           rules: [{            

      test: /.css$/,        

          use: [ ‘style-loader’, ‘css-loader] 

            }]   

     }, 

    Css-loader: css文件打包到js中,常常配合style-loader一起使用,将css文件打包并插入到页面中

    Style-loader: 使用<style>css-loader内部样式注入到HTML页面

     

    Loaders是Webpack最重要的功能之一,这也是Webpack如此盛行的原因。通过使用不同的Loader,从而对不同的文件格式进行特定处理。

    比如说可以把SASS文件的写法转换成CSS,而不在使用其他转换工具;把ES6或者ES7的代码,转换成大多浏览器兼容的JS代码;把React中的JSX转换成JavaScript代码。需要注意的是:所有的Loaders都需要在npm中单独进行安装,并在webpack.config.js里进行配置。Loaders的配置型简单梳理:

      test:用于匹配处理文件的扩展名的表达式,这个选项是必须进行配置的;

      use:loader名称,就是你要使用模块的名称,这个选项也必须进行配置,否则报错;

      include/exclude:手动添加必须处理的文件(文件夹)或屏蔽不需要处理的文件(文件夹)(可选);

      query:为loaders提供额外的设置选项(可选)

    7.Css中的图片处理-- url-loader

    css中添加背景图,执行webpack,图片路径错误

    安装:npm install --save-dev file-loader url-loader

    使用:{
        test: /.(png|jpg|gif|jpeg|bmp)/i,
        use: [{
            loader: 'url-loader',
            options: {
                limit: 500000
            }
        }]
    }

    test:/.(png|jpg|gif)/是匹配图片文件后缀名称

    use:是指定使用的loader和loader的配置参数

    limit:是把小于500000B的文件打成Base64的格式,写入JS

     

    url-loader会将引入的图片编码,生成dataURl。DataURI是一种提供让外置资源的直接内嵌在页面中的方案。相当于把图片数据翻译成一串字符。再把这串字符打包到文件中,最终只需要引入这个文件就能访问图片了。当然,如果图片较大,编码会消耗性能。因此url-loader提供了一个limit参数,小于limit字节的文件会被转为DataURl,大于limit的还会使用file-loader进行copy。File-loader可以解析项目中的url引入(不仅限于css),根据我们的配置,将图片拷贝到相应的路径,并且修改打包后文件的引用路径,使之指向正确的文件。

    四. webpack优化

    8. Css分离--extract-text-webpack-plugin

    步骤:

    1.安装 npm install --save-dev extract-text-webpack-plugin

    2. require引入const extractTextPlugin = require("extract-text-webpack-plugin")

    3.Plugins设置: new extractTextPlugin("/css/index.css")

    4. 修改css-loader{

                  test: /.css$/,

                  use: extractTextPlugin.extract({

                    fallback: "style-loader",

                    use: "css-loader"

                  })

                }

    8.Css分离导致图片路径错误-- publicPath

    publicPath:是在webpack.config.js文件的output选项中,主要作用就是处理静态文件路径的。

    webpack.config.js中声明对象
    var website ={    

    publicPath:http://127.0.0.1:9090/

    }

    Output配置

    output:{           

      path:path.resolve(__dirname,'dist'), 

    filename:'[name].js',      

      publicPath:website.publicPath    

    }

    publickPath是用来存放静态文件的,它的值是我们的本机ip或者devServer配置的IP和端口

    9. img标签添加图片-- html-withimg-loader

    1)在img标签中直接引入图片,执行wbbpack命令 —-- 报错

    安装:npm install --save  html-withimg-loader

    使用:Webpack.config.js

    {
        test: /.(htm|html)$/i,
        use: ['html-withimg-loader']
    }

    2)将图片打包至image文件夹

    options: {
        limit: 80000,
        outputPath: 'images/'
    },

    10.消除未使用的CSS --- PurifyCSS

    安装:npm i -D purifycss-webpack purify-css

    使用:

            1)const PurifyCSSPlugin = require("purifycss-webpack")

            2)配置plugins

           new PurifyCSSPlugin({

             paths: glob.sync(path.join(__dirname, 'src/*.html')),

             })

    注意:

    1. purifycss-webpack 安装依赖于purify-css,所以需要都安装

    2.这里我们用到了glob,glob是node中的模块,引入glob主要是用来根据某些规则匹配文件的

    3.必需要配合extract-text-webpack-plugin(css分离)插件使用

    purifycss-webpack 依赖于 purify-css

    paths,主要是需找html模板,purifycss根据这个配置会遍历你的文件,查找哪些css被使用了

    Glob:因为我们需要同步检查html模板,所以我们需要引入node的glob对象使用。在webpack.config.js文件头部引入glob

     

    11. Less文件的打包和分离-- less-loader

    即:将less转换成css文件进行打包和分离(同css文件分离)

    安装less npm install –save-dev less

    使用

    {
        test: /.less$/,
        use: extractTextPlugin.extract({
            fallback: "style-loader",
            use: ["css-loader", "less-loader"]
        })
    }

    对于less文件的打包和分离和css文件也是几乎一样,只是多了把less转换成css这一步,下载好less-loader 之后就可以了。

    webpack的强大除了可以转换less sass之外还可以使用babel转换es6 es7 jsx等为普通的js

     

    12支持babel

     

    安装:npm install --save-dev babel-core babel-loader babel-preset- env 

    使用: webpack.config.js配置

    {
        test: /.(jsx|js)$/,
        use: {
        loader: babel-loader’,
        options: {  // 选项
             presets: [  // 渲染器
            env", "react"]}
        },
       exclude: /node_modules/
    }

    注意:后期随着项目的增大可能会有很多渲染器,这是这么写的话可读性不太好了,我们可以将选项写在.babelrc文件中。

    .webpack.config.js

    {
        test: /.(jsx|js)$/,
        use: {
        loader: ‘babel-loader
        },
       exclude: /node_modules/
    }

    .babelrc

    {
      "presets": [
        "react",
        ”env"
      ]
    }

     

    11. 抽离第三方类库

     

    Webpack.config.js

    entry:{    

    entry:'./src/entry.js',    

    jquery:'jquery',   

    vue:'vue

    '},

    new webpack.optimize.CommonsChunkPlugin({

    name:[‘jquery’,‘vue’],

    filename:"assets/js/[name].js",  

    minChunks:2

    }),

     

     

    12. 提取公共代码--CommonsChunkPlugin

     

    步骤:

     

    1.将所有页面都依赖的库比如:vue react react-dom等提取到一个单独的文件,一般叫做base.js(基础运行环境)

     

    2.剔除各个页面中的base.js之后的代码,再找出它们以来的公共部分的代码,放到common.js

     

    3.将各个页面生成单独的文件,这些文件将不包含base.js,common.js中的部分,只包含个页面单独需要的部分代码

     

    具体实现需要借助于Webpack 内置的用于提取多个 Chunk 中公共部分的插件 CommonsChunkPlugin

     

     

     

    大型网站通常会由多个页面组成,没个页面都是一个独立的单页应用。但是由于所有页面采用的都是相同的技术栈,可能就会导致有很多重复的代码。如果每个页面的代码都把这些公共的部分包含进去,会造成一些问题。

     

    1)相同资源重复加载,浪费用户流量和服务器成本;2)页面需要加载的资源太大,导致页面首屏加载缓慢,影响用户体验

     

    那么如果我们能将公共的代码提取出来,那么用户在访问其中一个网页的时候,页面的公共代码文件就已经被浏览器缓存起来,用户再访问其他页面的时候,公共代码不会重新加载而是从缓存中获取。如此,虽然首屏访问得不到优化,但是后续页面速度大大提升,并且减少了网络流量和服务器成本。那么怎么提取公共代码呢???

     

    1.将所有页面都依赖的库比如:vue react react-dom等提取到一个单独的文件,一般叫做base.js(基础运行环境)

     

    2.剔除各个页面中的base.js之后的代码,再找出它们以来的公共部分的代码,放到common.js

     

    3.将各个页面生成单独的文件,这些文件将不包含base.js,common.js中的部分,只包含个页面单独需要的部分代码

     

     

     

    在线上文件中,对静态文件的文件名都附加根据文件内容计算出的hash值,比如base_123a.js,以长期缓存,只要不升级基础库的版本,base的内容就不会变化,hash就不会更新,缓存也不会更新,每次更新代码common.js和js会因文件内容变化而导致hash值被更新。

     

    每次发布浏览器都会使用被缓存的 base.js 文件,而不用去重新下载 base.js 文件。 由于 base.js 通常会很大,这对提升网页加速速度能起到很大的效果。

     

    const CommonsChunkPlugin = require('webpack/lib/optimize/CommonsChunkPlugin');
    new CommonsChunkPlugin({ 

     

    chunks: [‘a’, ‘b’], // 从哪些 Chunk 中提取,默认从所有已知chunk获取

     

    name: 'common’ // 提取出的公共部分形成一个新的 Chunk

     

     })

     

    require('webpack/lib/optimize/CommonsChunkPlugin');
    new CommonsChunkPlugin({ 

     

    chunks: [‘a’, ‘b’], // 从哪些 Chunk 中提取,默认从所有已知chunk获取

     

    name: 'common’ // 提取出的公共部分形成一个新的 Chunk

     

     })

     

    以上是将a,b的公共代码提取到了common中,接下来我们还需要从common中,提取出基础运行库。

     

    需要以下操作:

     

    1)首先需要在项目中写一个base.js来描述项目所以来的模块,比如:

     

    // 所有页面都依赖的基础库

     

     import 'react';

     

     import 'react-dom';

     

     // 所有页面都使用的样式

     

     import './base.css';

     

    2)再修改webpack

     

    module.exports = {

     

    entry: { 

     

    base: './base.js' 

     

    },

     

     };

     

     

     

    new CommonsChunkPlugin({ 

     

    // 从 common 和 base 两个现成的 Chunk 中提取公共的部分 

     

    chunks: ['common', 'base'], // 把公共的部分放到 base 中 name: 'base' 

     

    })

     

     

     

    <script src="base.js"></script> 

     

    <script src="common.js"></script> 

     

    <script src="a.js"></script>

     

    13.打包后如何调试

     

    主要有以下几种方式:

     

    1)source-map:生成独立map文件,包含行列信息(信息最详细完整)

     

    2)cheap-module-source-map:生成独立map文件,只包含行信息

     

    3)eval-source-map:js文件内生成sourcemap,包含行列信息

     

    4)cheap-module-eval-source-map:就是文件内生成sourcemap,只包含行信息

     

    注意:1)source-map模式下会输出质量最高最详细的source Map ,但是会造成构建速度缓慢,在开发过程中如果频繁修改,会增加等待时间;

     

    2)source Map会被暴漏出去,所以在生产环境下不建议使用source-map;

     

    3)建议在开发环境下使用cheap-module-eval-source-map或者eval-source-map,开发环境下使用hidden-source-map,可生成最详细的source Map,但不会暴漏源码

     

    一点一滴累积,总有一天你也会成为别人口中的大牛!
  • 相关阅读:
    图片轮播切换
    php用get_meta_tags轻松获取网页的meta信息
    PHP创建桌面快捷方式实例
    php 获取网站根目录的写法
    php mkdir 创建多级目录实例代码
    php计算剩余时间的自定义函数
    php实现获取汉字的首字母实例
    PDO封装函数
    Struts动态表单(DynamicForm)
    [WPF]静态资源(StaticResource)和动态资源(DynamicResource)
  • 原文地址:https://www.cnblogs.com/fancyLee/p/9060244.html
Copyright © 2020-2023  润新知