webpack教程

作者: js_hcl | 来源:发表于2019-02-14 15:17 被阅读28次

    一、webpack和npm的关系

    • npm是包管理器,及可以执行命令包(webpack可以看成是功能强大的命令包,除了webpack还有其它如webpack-dev-server);
    • webpack可以看成是功能强大的命令包:它还可以执行其它的功能包(装载机,插件)

    二、全局安装/项目安装?[1]

    重点就在这个包是否要作为CMD命令来使用及本地项目是否都差不多,因此放在全局

    1. 这个包要作为CMD命令使用:要全局安装 。如yarn cnpm webpack-dev-server等

    即安装到node_global,因为node_global在系统环境中配置了路径,故而里面的脚本能在cmd中直接运行
    此时这个命令的运行环境是全局环境:对应全局的webpack版本

    1. 不作为CMD命令使用:项目安装

    在package.json的scripts中也可以执行命令包,此时通过npm run 命令别名来执行
    因为Npm会临时把本地项目命令加载到系统环境path中,故而命令包放在本地也能通过npm run来执行
    如果本地有安装,则执行本地的。否则执行的是全局的命令包。对应的执行环境webpack也是一样的。

    三、打包前的准备工作(操作的webpack为3.8.1)

    • 创建项目: $ npm init
    • 全局安装webpack:$ npm install webpack -g 及脚手架$ npm install webpack-cli -g

    全局安装是为了CMD使用webpack 命令

    • 本地安装webpack: $ npm install webpack --save-dev

    四、js的打包

    方式①:$ webpack 源文件 目标文件 即:把源文件js打包到目标文件
    如:$ webpack ./src/app.js ./dist/main.js

    其它参数:

    • --watch 开启热跟新
    • -p 压缩目标文件
    • -d 调试时,方便定位源文件

    问题:

    • 命令行太长,写法比较复杂
    • 直接采用的是webpack命令,此时,运行环境为 全局的webpack包,并非项目的webpack版本,可能会产生和项目的一些冲突

    方式②:通过配置文件,来简化webpack命令

    创建配置文件 webpack.config.js
    module.exports={
       entry:'./src/app.js',
       output:{
          path: __dirname + '/dist', //__dirname 是Node的变量,表示根目录。注意:path只能是绝对路径
          filename: 'main.[hash:5].js' //[hash:5]表示取hash的5位,这边是为了更新浏览器本地缓存
    }
    //json文件不能注释,这边是为了解释说明用的
    

    因为webpack会自动会查找webpack.config.js,且这边已经配置好了源文件及目标文件
    此时可以:$ webpack 即可打包。或$ webpack --watch

    问题:

    • 命令行还是不够简洁,一些参数还是没办法配置
    • (同上)直接采用的是webpack命令,此时,运行环境为 全局的webpack包,并非项目的webpack版本

    方式③:通过package.json的scripts来运行脚本

    修改package.json的scripts:
    "scripts": {
         "build": "webpack --watch -d",
         "prod": "webpack -p"
     }
    

    此时,可以直接$ npm run build$ npm run prod来运行脚本

    优点:

    • 命令全都由npm来运行,且命令简洁明了(便于知道有哪些命令)
    • npm来运行,所以采用的是项目的脚本(包括其它的脚本也是一样)

    五、结合html

    前面已经学会js的打包,但毕竟运行在浏览器的入口是html,那怎么和html结合呢?

    方式①:创建html,手动引入打包后的js

    问题:

    • 打包后的style,script标签要手动写入html。麻烦
    • 以及hash问题,每次生成的打包文件名还不一样,又要重新写入html。麻烦

    方式②:使用html-webpack-plugin插件

    安装插件
    $ npm install html-webpack-plugin --save-dev 
    

    使用插件(在webpack.config.js中引入及挂载)
    
    引入:
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    
    挂载:
    plugins: [
     new HtmlWebpackPlugin({
        template:"./src/index.html", //html的模版文件
        filename: 'one.html',    //生成目标html的名字
        minify: {collapseWhitespace:true} ,//压缩html及配置压缩类型
        hash:true//会在所有注入的静态资源添加webpack每次编译产生的唯一hash值
     })
    ]
    
    
    //hash:true的效果
    <script type="text/javascript" src="main.dce13.js?dce1306176497ad4a85d"></script></body>
    可以发现dce13:为main.[hash:5]生成的hash值
    ?dce1306176497ad4a85d为这次生成的hash值,所有静态文件都添加了这个
    

    html-webpack-plugin详细配置点击查看
    minify的详细配置点击查看


    高级篇----多html的配置

    • 从实际意义出发,肯定需要配置多入口
    之前entry是string类型,这次我们采用array类型
    
    entry: {
       "entry1":'./src/app.js', //其中,"entry1"作为chunk代码块
       "entry2":'./src/app1.js',
       "entry3":'./src/app2.js',
    },
    

    使用插件
    plugins: [  //tips: plugins执行顺序也是从后到前执行。即先执行底下的插件,再上面的插件
     new HtmlWebpackPlugin({
        template:"./src/index_other.html",
        filename: 'two.html',      //这个是第二个html的出口
        minify: {collapseWhitespace:true} ,
        hash:true,
        chunks:['entry2','entry3']  //这边测试处理两个,也可以通过excludeChunk:['entry1'] 取余
     }),
     new HtmlWebpackPlugin({
        template:"./src/index.html",
        filename: 'one.html',    
        minify: {collapseWhitespace:true} ,
        hash:true,
        chunks:['entry1']   //这个配置是要处理的chunk代码块,默认为all即所有入口的都处理
     })
    ]
    --------------------------------------------------------
    说明:
    chunks:[] //数组内的值为entry配置里面的key值。这边即'entry1','entry2','entry3'
    excludeChunk:[]//这个配置是除了数组内的chunk代码块会去处理。即取反
    

    这边还有个问题:多个html-webpack-plugin插件处理入口,于是会生成多个目标js。
    
    之前:
    output:{
        path: __dirname + '/dist',
        filename: 'main.[hash:5].js' //多html-webpack-plugin插件时,会生成多个同名的该文件,会同名覆盖
    }
    
    改为=>
    output:{
        path: __dirname + '/dist',
        filename: '[name].[hash:5].js' //name为对应entry的chunk名,同上
    }
    
    说明:[name]表示为对应entry的chunk名,同上
    

    总结:对比一个html,区别在于:
    需要多个入口,然后使用多个html-webpack-plugin插件处理入口对应的chunk,然后生成多html

    六、结合css

    前面学习了js的打包,以及把打包后的Js结合html,结合html我们采用插件来自动化帮我们处理一些事情。
    但是怎么结合css呢,css不是浏览器入口,只能通过源js引入该css。再处理
    但是webpack默认只认得js,因此要采用装载机来处理css,再放到html中。

    方式①:使用'style-loader', 'css-loader' 。这种是<style>样式的方式

    安装装载机
    $ npm install css-loader style-loader --save-dev
    

    使用装载机(在webpack.config.js中挂载) 相比插件不用引进
    
    module: {
       rules: [
         {
           test: /\.css$/,    //正则表达式,匹配对应的后缀文件,然后用底下对应的装载机处理
           use: [ 'style-loader', 'css-loader' ]    //装载顺序为***从右到左***
         }
       ]
    }
    

    说明:

    • css-loader:即:编译。加载.css文件,注入到js文件中,以字符串的形式存在
    • style-loader:即:提取。使用<style>将css-loader内部样式注入到我们的HTML页面
    • css-loader/style-loader详细配置点击查看
    • 这种方式在html生成的是<style>标签

    方式②:结合extract-text-webpack-plugin插件:实现css分离成文件。这种是<link>样式的方式

    安装插件
    $ npm install  extract-text-webpack-plugin  --save-dev
    

    使用插件
    
    //这边对比css-loader/style-loader的区别
    module: {
      rules: [
         {
           test: /\.css$/,
           use:ExtractTextPlugin.extract({
             fallback: 'style-loader',    //提取要用到的装载机
             use: [ 'css-loader' ]    //编译要用到的装载机
           })
         }
       ]
    }
    
    
    以及配置plugins:
    
    plugins{
      new ExtractTextPlugin('style.css')  //生成目标css的文件名为style.css
    }
    

    说明:

    • 通过extract-text-webpack-plugin插件实现了css的分离,而不是注入js中
    • extract-text-webpack-plugin详细配置点击查看
    • 和webpack4.0+ 不兼容
    • 这种方式在html生成的是<link>标签
    • 所以和第一种方式的优劣势对比即为:<style>和<link>样式的优劣势对比 及css有独立hash等

    这边补充对于scss的css文件的处理

    安装scss装载机:
    $ npm install sass-loader node-sass --save-dev
    

    方式一下使用sass-loader装载机:
    module: {
       rules: [
         {
           test: /\.scss$/,    //这边匹配文件后缀为.scss
           use: [ 'style-loader', 'css-loader' ,"sass-loader"]    //只是这边后面增加该装载机
         }
       ]
    }
    
    ------------------------------------------------------------------
    方式二下使用sass-loader装载机:
    module: {
      rules: [
         {
           test: /\.scss$/,
           use:ExtractTextPlugin.extract({
             fallback: 'style-loader',    
             use: [ 'css-loader',"sass-loader" ]    
           })
         }
       ]
    }
    
    
    以及配置plugins:
    
    plugins{
      new ExtractTextPlugin('style.css')  
    }
    

    其它补充

    • 添加hash: plugins: [new ExtractTextPlugin('style.[hash:5].css')]

    七、webpack-dev-server插件的使用

    前面有介绍CMD命令包对于全局安装或本地安装的选择,点击回顾
    方式①:全局安装 $ npm install webpack-dev-server -g
    此时,在CMD即可使用该命令:$ webpack-dev-server //注意此时运行环境为全局的Webpack版本


    方式②:项目安装 $ npm install webpack-dev-server --save-dev
    此时可以通过配置scripts可以让npm来运行脚本

    "scripts": {
      "dev": "webpack-dev-server"
    }
    

    此时,可以直接npm run dev来开启本地服务


    补充

    webpack.config.js中配置
    
    devServer: {
      port: 9000,  //这边配置端口号
      open:true  //这边会自动打开浏览器
    },
    

    说明

    • 配置webpack-dev-server 运行时报错配置 Can't resolve 'webpack/hot/dev-server' 。说明项目中,没有安装webpack
    • webpack-dev-server生成的包并没有放在你的真实目录中,而是放在了内存中
    • 和webpack4.0+不兼容,这边webpack@3.8.1安装2.9.1
    • webpack-dev-server的详细配置点击查看
    • 对比webpack --watch避免了打包文件及实现了热更新

    八、

    # babel6配置过程

    九、区分生产环境和开发环境

    • 配置部分区分
    • 方式①:在webpack.json的scripts运行脚本时,增加变量并赋值

    eg:"prod": " SET NODE_ENV=production & SET hcl=huchunlin && webpack -p",
    配置部分使用:console.log(process.env.NODE_ENV);console.log(process.env.hcl);
    说明:process.env.变量来访问
    window系统需要SET 。max系统不需要

    • 方式②:不同命令进入,即会执行不同的配置文件

    eg:"prod": " webpack -p --config ./config/prod.js",
    即通过--config来执行指定配置文件

    • 方式③:相结合
    • 源代码(打包后的文件)区分

    通过webpack.DefinePlugin来定义源代码的全局变量。在编译时会进行替换

     webpack.config.js中=>定义全局变量
    -----------------------------------------------------------------
     plugins: [
       new webpack.DefinePlugin({
         "hcl": JSON.stringify('这个是在webpack.config定义的变量')
       })
     ]
    

    源代码中,比如在app.js中=>使用全局变量
    -----------------------------------------------------------------
     console.log(hcl)
    
    • 配置文件和源代码都要能区分:结合①和②

    1. 二、全局安装/项目安装

    相关文章

      网友评论

        本文标题:webpack教程

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