zoukankan      html  css  js  c++  java
  • webpack实用配置

    开车之前,先介绍一些npm的命令:

    :D
    进入D盘

    mkdir webapp

    创建webapp文件夹

    cd webapp

    进入webapp文件夹

    mkdir webapp && cd webapp

    以上两步创建和进入文件夹可以合并为一步

    npm init -y

    快速生成package.json文件

    npm install xxx --save-dev

    //安装模块并加入到开发依赖中,比如webpack

    npm install xxx --save

    安装模块并加入到生产依赖中,比如Jquery

    npm install xxx@2.3.0

    下载指定版本

    npm view webpack versions --json

    如果忘记版本号,可以列出所有版本号

    npm install -g cnpm --registry=https://registry.npm.taobao.org

    下载淘宝镜像源,国内npm下载很慢,而且有些包下下来貌似会有问题,比如node-sass。

    下载之后就可以直接使用了,使用方式跟Npm一样,只不过是改成cnpm

    cls

    清空命令提示符窗口内容




    webpack

    1. html篇

    介绍完npm基本的东西后,下面开始撸webpack

    有关webpack的基本概念建议到官网查看,解释的更为清楚,下面只简单介绍。

    1.  在根目录下生成package.json文件: npm init -y
    
    
    2.  安装webapck cnpm install webpack --save-dev
    
    
    3. 创建webpack.config.js文件: echo > webpack.config.js
    
     
    var path=require("path");
    module.exports={
       <!--  要打包的文件 -->
        entry:"./index.js",
    
        output:{
            <!-- 指定打包后的文件名字 -->
            filename:"bundle.js",
            <!-- 打包后的文件路径 -->
            path:path.resolve(__dirname,"dist")
        }
    }
    4.创建src目录,并在src目录下创建index.html, index.js文件并随便输一点东西
    
        window.onload=function(){
             alert(1)
        }
       
    5.执行 webpack 命令,可以发现webpack帮我们在dist下生成了一个main.js文件,打开main.js并拖到最下面你会发现index.js的内容就在里面。
    
    打包完之后,我们在dist生成了js文件,但是我们的index.html在src下面,你可以手动的复制src下的html文件到dist目录下,并且将打包后的js文件引入。不过像我们这么懒的人,还是希望webpack能够帮我们在dist下也生成index.html,要是能自动引入打包后的js文件,那就再好不过了。这时候,是时候来一发插件了。
    
    
    6.cnpm install html-webpack-plugin --save-dev
    修改webpack.config.js
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    var path = require("path")
    module.exports = {
        entry:"./index.js",
        output: {
            path: path.resolve(__dirname, 'dist'),
             filename:"bundle.js",
        },
        plugins: [new HtmlWebpackPlugin({
            title: "测试"       
        })]
    };
    重新执行命令 webpack ,你会发现在dist下多生成了一个index.html文件,打开发现还有一个script的标签引用着我们打包后的文件,nice。
    
    不过问题又来了,html文件很简陋,就是emmet帮我们生成的Html5文件,你可能希望还带有更多的 meta标签,像这样的
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
        <meta name="format-detection" content="telephone=no, email=no"/>
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title></title>
    </head>
    <body>
        <header></header>
        <nav></nav>
        <div id="app"></div>
        <footer></footer>
    </body>
    此时,你可以自己写一个模板,只需要告诉html-webpack-plugin插件文件的位置就可以了。
    修改webpack.config.js
    plugins: [
        new htmlWebpackPlugin({
            title:"首页",
            <!-- 指定模板位置 -->
            template:'./src/index.html',
            <!-- 指定打包后的文件名字 -->
            filename: 'index.html'
        })
    ]
    对于多疑症的你,打包多次后你可能会怀疑文件修改生效了没有,此时你可以安装clean-webpack-plugin插件,在每次打包时,先删除原来的dist目录,再重新打包,这样就可以放心的睡觉,不用担心门没关了。
    7.cnpm install clean-webpack-plugin --save-dev
    plugins:[
        new htmlWebpackPlugin({
            title:"首页",
            template:'./src/index.html',
            filename: 'index.html'
        }),
        <!-- 每次打包前先删除dist目录 -->
        new CleanWebpackPlugin(['dist'])
    ]

    css篇

    以往我们写css都是写好后手动通过link引入到html,使用webpack后,你将不再需要手动做这些操作,只需要在js文件中引入,webpack就能帮你搞定,不过需要一些loader和plugin的支持。

    cnpm install --save-dev css-loade style-loader

    修改webpack.config.js
    
    
    ###为了处理css文件我们需要多配置一个module参数,并使用css-loader来将css文件打包到成“字符串”到js文件中,并使用style-loader将打包后的字符串提取出来并append<style>标签到head下面 
    
    var path=require("path");
    var htmlWebpackPlugin=require('html-webpack-plugin');
    var CleanWebpackPlugin = require('clean-webpack-plugin');
    
    module.exports={
      entry:{
        main:'./src/index.js'
      },
      output:{
        filename:"bundle.js",
        path:path.resolve(__dirname,'dist')
      },
      module:{
        rules:[   
            <!-- test检测到以xxx结尾的东西use对应的loader -->
            {
                test: /.css$/,
                use: [ 'style-loader', 'css-loader' ]         
            }
        ]
      },
      plugins:[
        new htmlWebpackPlugin({
          title:"首页",
          template:'./src/index.html',
          filename:"index.html"
        }),
        new CleanWebpackPlugin(['dist'])    
      ]
    }
    哦,听说你想用sass 预处理 器,那么只需要在use里加多一个sass-loader,并安装依赖
    cnpm install --save-dev sass-loader node-sass
    
    rules:[  
        {
            test: /.scss$/,
            use: [ 'style-loader', 'css-loader',"sass-loader" ]         
        }
    ]
    什么,想要自动补全浏览器后缀autoprefixer?没问题
    cnpm install --save-dev  postcss-loader
    
    rules:[  
            {
                test: /.s?css$/,
                use: [
                        {
                            loader: "style-loader"
                        }, 
                        {
                            loader: "css-loader"
                        }, 
                        {
                            loader: 'postcss-loader',
                            options: {
                                plugins:  [     
                                     require('autoprefixer')({
                                      browsers: ['last 10 versions']
                                  })
                                ]
                            }
                        },
                        {
                            loader: "sass-loader"
                        }
                    ]         
            }
        ]

    这里需要注意,use里面的执行顺序是倒序的 ,,webpack会以倒叙的方式处理并将处理后的结果返回给上一个loader,最后通过style-loader将文件的内容append到head下面的style标签里。

    教练,我还想要自动刷新

    当你修改一点文件后,你需要重执行命令新编译文件,然后刷新页面。如果你使用过gulp的自动刷新比如live-reload,那你也一定希望webpack也有同样的功能,webpack-dev-server满足你的需求并且能够给你更多。

    安装webpack-dev-server到开发依赖  cnpm install --save-dev webpack-dev-server
    <!-- 在package.json中加入: -->
    "scripts": {
        "dev": "webpack-dev-server"
    }
    通过npm run dev即可执行创建一个服务器,打开localhsot:8080
    此时再修改文件,你会发现页面自动刷新了并且修改生效了,不过你看不到重新编译后的文件在哪里,应为webpack-dev-server将文件编译到了内存中 ,比起重新生成文件效率会更高,当然只适用于开发阶段。
    启动服务后,如果你 还想让他自己 打开Localhost,还想 使用模块热重载 ,可以加多一个配置
    devServer:{
             open:true,  
             hot: true,// 告诉 dev-server我们想用HMR模式                   
      }
    开发的时候我们并不在意 style这种形式,但是我们希望在生产环境下 css能从js文件宏分离出来,我们希望能css能跟js并行加载,而且可以避免因为Js文件过大,加载慢而产生的flash of unstyle(无样式页面闪烁)。
    使用“extract-text-webpack-plugin”插件来分离css代码。 

    修改webpack.config.js

    cnpm install --save-dev  extract-text-webpack-plugin
    var path=require("path");
    var webpack=require('webpack');
    var htmlWebpackPlugin=require('html-webpack-plugin');
    var CleanWebpackPlugin = require('clean-webpack-plugin');
    var ExtractTextPlugin = require("extract-text-webpack-plugin");
    
    var extractSass = new ExtractTextPlugin({
        filename: "[name].[contenthash].css",
        disable: process.env.NODE_ENV === "development"
    });
    
    //通过设置环境变量来告诉webpack我们在development模式下不需要提取css到单独在文件,只有当不是development下(也即是production)才需要提取文件。
    
    module.exports={
      entry:{
        main:'./src/index.js'
      },
      output:{
        filename:"bundle.js",
        path:path.resolve(__dirname,'dist')
      },
      devServer:{
             open:true,  
             hot: true, <!-- 告诉 dev-server我们想用HMR模式 -->                
      },
      module:{
        rules:[
            {
            test: /.s?css$/,
                  use: extractSass.extract({
    
                      use: [
                      {
                          loader: "css-loader"
                      }, 
                      {
                        loader: 'postcss-loader',
                        options: {
                          plugins:  [     
                            require('autoprefixer')
                          ]
                        }
                      },
                      {
                          loader: "sass-loader"
                      }],
                      fallback: "style-loader"
                  })
              }
        ]
      },
      plugins:[
        <!-- 使用此插件来支持热重载 -->
        new webpack.HotModuleReplacementPlugin(),
    
        new htmlWebpackPlugin({
          title:"首页",
          template:'./src/index.html',
          filename:"index.html"
        }),
        new CleanWebpackPlugin(['dist']),
        extractSass
      
      ]
    }

    修改package.json ,本人为window10系统

    "scripts": {
        "dev": "set NODE_ENV=development&&webpack-dev-server",
        "build":"webpack -p"
    }
    分别执行npm run dev以及npm run build,你会发先npm run build时css文件被提取到一个单独的文件了。

    js篇

    --------------------------------好累啊下面直接上代码了

    为了使用promise,async等es6,7语法,同时兼容低版本浏览器,你还需要将js转码为es5。

    你需要安装以下依赖包
    cnpm install --save-dev
    
        "babel-core": "^6.25.0",
        "babel-loader": "^7.0.0",
        "babel-plugin-transform-object-rest-spread": "^6.23.0",
        "babel-plugin-transform-runtime": "^6.23.0",
        "babel-preset-env": "^1.5.2",
    
    在module下增加:
    {
        test: /.js$/,
        exclude: /node_modules/,
        use: {
            loader: 'babel-loader',
            options: {
                presets: ['env'],
                plugins: ['transform-runtime']
            }
        }
    }

    写一点async或者prmise代码,打包后发现promise变成了_promise2

    代理



    前后端分离开发时经常还会遇到跨域的问题,还可以利用devServer来进行代理

     devServer:{
        open:true,  
        hot: true, 
        proxy: {
            '/api/': {
                target: 'http://baidu.com',
                secure: false,
                changeOrigin: true
            }
        }
    
    $.ajax({
        url:'/api/',
        success:function(res){
            console.log(res)
        },
        error:function(res){
            console.log(res)
        }
    })

    图片,字体篇

    {
        test: /.(png|jpe?g|gif|svg)(?.*)?$/,
        loader: 'url-loader',
        query: {
            limit: 8000,
            <!-- 小于8k的转化为Base64 -->
            name: '[name].[hash:7].[ext]'
        }
    }, 
    
    {
        test: /.(woff2?|eot|ttf|otf)(?.*)?$/,
        loader: 'url-loader',
        query: {
            limit: 8000,
             name: 'font/[name].[hash:7].[ext]'
        }
    }
    你可能想要把所有img或者font文件分别放到一个img或者font文件夹下,可以这么写:name: 'img/[name].[hash:7].[ext]' 
    如果你不想下载字体文件下来,可已上传到阿里字体库并使用阿里的在线字体图标,并复制自己的文件的在线地址。
    在css里面像这么用:@import url("//at.alicdn.com/t/font_s0zqwb6by3lhm2t9.css");     

    打包多文件

    var path=require("path");
    var webpack=require('webpack');
    var htmlWebpackPlugin=require('html-webpack-plugin');
    var CleanWebpackPlugin = require('clean-webpack-plugin');
    var ExtractTextPlugin = require("extract-text-webpack-plugin");
    
    var extractSass = new ExtractTextPlugin({
        filename: "[name].[contenthash].css",
        disable: process.env.NODE_ENV === "development"
    });
    
    module.exports={
      entry:{
        "main":'./src/js/index.js',
        "car":"./src/js/car.js",
        "goods":"./src/js/goods.js"
      }, 
     
      output:{
        filename:"[name].[hash].js",
        path:path.resolve(__dirname,'dist')
      },
     
      devServer:{
            open:true,  
            hot: true,
            proxy: {
                '/api/': {
                    target: 'http://baidu.com',
                    secure: false,
                    changeOrigin: true
                }
            }
            
      },
    
      module:{
        rules:[
        
          {
            test: /.s?css$/,
                  use: extractSass.extract({
                      use: [
                      {
                          loader: "css-loader"
                      }, 
                      {
                        loader: 'postcss-loader',
                        options: {
                            plugins:  [     
                                require('autoprefixer')({
                                  browsers: ['last 10 versions']
                              })
                            ]
                        }
                      },
                      {
                          loader: "sass-loader"
                      }],
                      fallback: "style-loader"
                  })
              },
              {
                  test: /.js$/,
                  exclude: /node_modules/,
                  use: {
                    loader: 'babel-loader',
                    options: {
                      presets: ['env'],
                      plugins: ['transform-runtime']
                    }
                  }
            },
            {
          test: /.html$/,
          use: ['html-withimg-loader']
        },
            {
                test: /.(png|jpe?g|gif|svg)(?.*)?$/,
                loader: 'url-loader',
                query: {
                    limit: 8000,
                    name: 'img/[name].[hash:7].[ext]'
                }
            }, 
            {
                test: /.(woff2?|eot|ttf|otf)(?.*)?$/,
                loader: 'url-loader',
                query: {
                    limit: 8000,
                     name: 'font/[name].[hash:7].[ext]'
                }
            }
        ]
      },
        plugins:[
            new webpack.HotModuleReplacementPlugin(),
            new htmlWebpackPlugin({
              title:"首页",
              template:'./src/index.html',
              filename:"index.html",
              chunks:["page/main/main"]
            }),
            new htmlWebpackPlugin({
              title:"购物车",
              template:'./src/index.html',
              filename:"car.html",
              chunks:["page/car/car"]
            }),
            new htmlWebpackPlugin({
              title:"商品",
              template:'./src/index.html',
              filename:"goods.html",
              chunks:["page/goods/goods"]
            }),
    
            new CleanWebpackPlugin(['dist']),
            extractSass,
            new webpack.ProvidePlugin({
                 $:"jquery",
                 jQuery:"jquery"
            }) 
            
        ]
    }
    上面这样写打包后文件都放在一个目录下,目录很乱,不方便管理,想让每个页面的js,css文件放在对应目录下,可以按下面这么写
    entry:{
        "page/main/main":'./src/js/index.js',
        "page/car/car":"./src/js/car.js",
        "page/goods/goods":"./src/js/goods.js"
      }
    如果多个文件都引用了一些其他库,比如Jquery,vue,你可能想把所有的公共库提取出来,利用common-chunk插件可以解决。即使你做的是spa单页面应用,你也可以将公共库从js文件中提取出来,每次修改时只修改业务逻辑而不重新打包库,从而可以缓存库文件。
    entry:{
            "main/main":'./src/js/index.js',
            "car/car":"./src/js/car.js",
            "goods/goods":"./src/js/goods.js"
            "vendor":["jquery","vue"]
      },
    
    plugins:[     
            new htmlWebpackPlugin({
              ...同上
              chunks:["page/main/main","vendor","mainfest"]
            }),
    
            new htmlWebpackPlugin({
              ...
              chunks:["page/car/car","vendor","mainfest"]
            }),
    
            new htmlWebpackPlugin({
              ...
              chunks:["page/goods/goods","vendor","mainfest"]
            }),
    
             new webpack.optimize.CommonsChunkPlugin({
                name:["vendor","mainfest"]
            })
        ]
    发现一个问题,在公司电脑dev-server-open自动打开的地址后面会带undefined,去掉undefined打开网址才正常

    代码文件可以上github查看

    https://github.com/linrunzheng/webpackGuide

    常用的配置就这样了,其他配置可以去webpack官网看。如果觉得本文对你有所帮助,麻烦点个start或者赞

    webpack3都出了,你还不会2吗?

     

     

    前面的话

      上文介绍了webpack入门,本文将详细介绍webpack实用配置

    版本号

      以entry.js打包为bundle.js为例,出口的filename可以设置为[id]、[name]、[hash]、[chunkhash]等替换形式,如下所示

    复制代码
    var webpack = require('webpack');
    module.exports = {
      entry: './entry.js', //入口文件
      output: {
        path: __dirname,//出口路径
        filename: '[id]-[name]-[hash].js'//出口名称
      }
    }
    复制代码

      则出口文件为0-main-0c1dce21f6c5db455fb4.js

      如果index.html要引用打包后的js文件,由于文件名称不确定,并不好解决。这时,就需要使用html-webpack-plugin插件。该插件并不是内置插件,所以需要安装

    npm install html-webpack-plugin

      HtmlWebpackPlugin简化了HTML文件的创建,以便为webpack包提供服务。这对于在文件名中包含每次会随着变异会发生变化的哈希的webpack bundle尤其有用

    复制代码
    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    module.exports = {
      entry: './entry.js', //入口文件
      output: {
        path: __dirname,//出口路径
        filename: '[id]-[name]-[hash].js'//出口名称
      },
      plugins: [
        new HtmlWebpackPlugin({
          title: 'match',//生成的html文件的标题为'match'
          filename: 'index.html'//生成的html文件名称为'index.html'
        })
      ]
    }
    复制代码

      通过以上的配置,如果在当前路径,index.html不存在,则生成;如果存在,则替换

      [注意]如果htmlwebpackplugin不进行配置,参数为空, plugins: [new HtmlWebpackPlugin()]。默认地,生成的html文件名称为'index.html',标题为'Webpack APP' 

    【标签位置】

      htmlwebpackplugin插件的常用设置是设置script标签插入的位置,默认插入到body标签中,但可以使用inject:'head',设置插入到head标签中

    复制代码
    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    module.exports = {
      entry: './entry.js', //入口文件
      output: {
        path: __dirname,//出口路径
        filename: 'js/[id]-[name]-[hash].js'//出口名称
      },
      plugins: [
        new HtmlWebpackPlugin({
          inject:'head',//将script标签插入到head标签中
          filename: 'index-[hash].html',//生成的html文件名称为'index.html'
        })
      ]
    }
    复制代码

    【图标设置】

      设置favicon属性,可以设置网页的小图标

    复制代码
    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    module.exports = {
      entry: './entry.js', //入口文件
      output: {
        path: __dirname,//出口路径
        filename: 'js/[id]-[name]-[hash].js'//出口名称
      },
      plugins: [
        new HtmlWebpackPlugin({
          favicon:'./icon.ico'
        })
      ]
    }
    复制代码

    【压缩】

      设置minify属性,可以压缩html文件,默认为false,即不压缩

    复制代码
    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    module.exports = {
      entry: './entry.js', //入口文件
      output: {
        path: __dirname,//出口路径
        filename: 'js/[id]-[name]-[hash].js'//出口名称
      },
      plugins: [
        new HtmlWebpackPlugin({
          minify:{
              removeComments: true,//删除注释
              collapseWhitespace:true//删除空格
          }
        })
      ]
    }
    复制代码

      使用webpack打包后的index.html代码如下

    <!DOCTYPE html><html><head><meta charset="UTF-8"><title>Webpack App</title></head><body><script type="text/javascript" src="js/0-main-8128c0c26a4449da7a05.js"></script></body></html>

    模板文件

      HtmlWebpackPlugin除了提供模块版本号的功能,还可以使用模板文件

      例如,模板文件为template.html,内容如下

    复制代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>template</title>
    </head>
    <body>
    <script src="test.js"></script>
    <div>test</div>    
    </body>
    </html>
    复制代码

      webpack配置文件如下

    复制代码
    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    module.exports = {
      entry: './entry.js', //入口文件
      output: {
        path: __dirname,//出口路径
        filename: 'js/[id]-[name]-[hash].js'//出口名称
      },
      plugins: [
        new HtmlWebpackPlugin({
          filename: 'index-[hash].html',//生成的html文件名称为'index.html'
          template:'template/template.html'//模板文件为'template.html'
        })
      ]
    }
    复制代码

      生成的index-[hash].html以'template.html'文件为模板

      [注意]如果在htmlwebpackplugin中使用了模板,则指定title不会生效,因为要以模板的title为准  

    复制代码
    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    module.exports = {
      entry: './entry.js', //入口文件
      output: {
        path: __dirname,//出口路径
        filename: 'js/[id]-[name]-[hash].js'//出口名称
      },
      plugins: [
        new HtmlWebpackPlugin({
          title:'test',
          filename: 'index-[hash].html',//生成的html文件名称为'index.html'
          template:'template/template.html'//模板文件为'template.html'
        })
      ]
    }
    复制代码

    【传参】

      模块文件当然是可以传参的,一般地,使用ejs语法。例如,在模板文件中,使用<%= htmlWebpackPlugin.options.title %>,即可读取htmlWebpackPlugin插件中'title'属性的值

      [注意]模板文件中的'htmlWebpackPlugin'是固定的,不能随意更改。与webpack.config.js文件中,require()该插件的命名无关

    复制代码
    //webpack.config.js
    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    module.exports = {
      entry: './entry.js', //入口文件
      output: {
        path: __dirname,//出口路径
        filename: 'js/[id]-[name]-[hash].js'//出口名称
      },
      plugins: [
        new HtmlWebpackPlugin({
          title:'test',
          template:'template/template.html',//模板文件为'template.html'
          dateData: new Date() 
        })
      ]
    }
    //template.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title><%= htmlWebpackPlugin.options.title  %></title>
    </head>
    <body>
    <div><%=htmlWebpackPlugin.options.dateData %></div>
    </body>
    </html>
    复制代码

    【模板组件】

      下面利用模板组件组合成一个html文件,以ejs模板语言为例

    复制代码
    //webpack.config.js
    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    module.exports = {
      entry: './entry.js', //入口文件
      output: {
        path: __dirname,//出口路径
        filename: 'js/[id]-[name]-[hash].js'//出口名称
      },
      plugins: [
        new HtmlWebpackPlugin({
          template:'template/template.html'})
      ]
    }
    //template.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
    <div>
        <% include  template/header.html %>
    </div>
    <ul>  
        <% var arr = [1,2,3,4,5] %>
        <% for(var i = 0; i < arr.length; i++){ %>  
            <li><%=arr[i] %></li>  
        <% } %>  
    </ul>  
    <div>
        <% include  template/footer.html %>
    </div>
    </body>
    </html>
    //header.html
    <div>我是头部</div>
    //footer.html
    <div>我是尾部</div>
    复制代码

      运行结果报错,提示子模板加载失败

      这是因为HtmlWebpackPlugin插件并不具备ejs模板语言所有的功能,其中一个就是不能识别<%include %>语句,这时需要安装一个ejs-compiled-loader

    npm install ejs-compiled-loader

      安装完成后,修改配置文件如下,表示使用ejs-compiled-loader来编译template.html

      [注意]该插件中的include路径相对于webpack配置文件的位置,而不是模板文件template.html的位置

    复制代码
    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    module.exports = {
      entry: './entry.js', //入口文件
      output: {
        path: __dirname,//出口路径
        filename: 'js/[id]-[name]-[hash].js'//出口名称
      },
      plugins: [
        new HtmlWebpackPlugin({
          template:'ejs-compiled-loader!template/template.html'})
      ]
    }
    复制代码

      结果如下

    多页面

      对于多页面来说,一般地,有多个入口文件。不同的html页面输出对应不同的入口文件。 插件plugins()是一个数组,每new一个HtmlWebpackPlugin(),就可以输出一个html页面。这里有两个重要的属性:chunks和excludeChunks,chunks表示所包含的入口文件,excludeChunks表示要排除的入口文件

    复制代码
    //webpack.config.js
    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    module.exports = {
      entry: {
          a:'./src/js/a.js',
          b:'./src/js/b.js',
          c:'./src/js/c.js'
      },
      output: {
        path: __dirname,//出口路径
        filename: 'js/[id]-[name]-[hash].js'//出口名称
      },
      plugins: [
        new HtmlWebpackPlugin({
              filename:'a.html',
              template:'src/template/template.html',
              title:'this is a',
              chunks:['a']
        }),
        new HtmlWebpackPlugin({
              filename:'b.html',
              template:'src/template/template.html',
              title:'this is b',
              chunks:['b']
        }),
        new HtmlWebpackPlugin({
              filename:'c.html',
              template:'src/template/template.html',
              title:'this is c',
              excludeChunks:['a','b']
        }),    
      ]
    }
    复制代码

      结果如下

    复制代码
    //a.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>this is a</title>
    </head>
    <body>
    <div></div>
    <script type="text/javascript" src="js/2-a-9828ea84bd8c12c19b5f.js"></script></body>
    </html>
    
    //b.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>this is b</title>
    </head>
    <body>
    <div></div>
    <script type="text/javascript" src="js/1-b-9828ea84bd8c12c19b5f.js"></script></body>
    </html>
    
    //c.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>this is c</title>
    </head>
    <body>
    <div></div>
    <script type="text/javascript" src="js/0-c-9828ea84bd8c12c19b5f.js"></script></body>
    </html>
    复制代码

    内联

      在前面的例子中,都是以链接的形式引入入口文件的。有时,为了追求性能,会将其处理为内联的形式。这里就需要安装一个扩展插件html-webpack-inline-source-plugin,专门用来处理入口文件内联的

    $ npm install --save-dev html-webpack-inline-source-plugin

      该插件的使用很简单,使用require()语句引入后,在插件plugins()新建一个html-webpack-inline-source-plugin对象,然后在html-webpack-plugin对象中添加inlineSource属性即可

    inlineSource: '.(js|css)$' // embed all javascript and css inline
    复制代码
    //webpack.config.js
    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    var HtmlWebpackInlineSourcePlugin = require('html-webpack-inline-source-plugin');
    
    module.exports = {
      entry: './entry.js',
      output:{
        path: __dirname,//出口路径
        filename: 'js/[id]-[name]-[hash].js'//出口名称
      },
      plugins: [
        new HtmlWebpackPlugin({
            inlineSource: '.(js|css)$'
        }),
        new HtmlWebpackInlineSourcePlugin()
      ]
    }
    复制代码

      结果如下

    复制代码
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8">
        <title>Webpack App</title>
      </head>
      <body>
      <script type="text/javascript">/******/ (function(modules) { // webpackBootstrap
    /******/     // The module cache
    /******/     var installedModules = {};
    /******/
    /******/     // The require function
    /******/     function __webpack_require__(moduleId) {
    /******/
    /******/         // Check if module is in cache
    /******/         if(installedModules[moduleId]) {
    /******/             return installedModules[moduleId].exports;
    /******/         }
    /******/         // Create a new module (and put it into the cache)
    /******/         var module = installedModules[moduleId] = {
    /******/             i: moduleId,
    /******/             l: false,
    /******/             exports: {}
    /******/         };
    /******/
    /******/         // Execute the module function
    /******/         modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
    /******/
    /******/         // Flag the module as loaded
    /******/         module.l = true;
    /******/
    /******/         // Return the exports of the module
    /******/         return module.exports;
    /******/     }
    /******/
    /******/
    /******/     // expose the modules object (__webpack_modules__)
    /******/     __webpack_require__.m = modules;
    /******/
    /******/     // expose the module cache
    /******/     __webpack_require__.c = installedModules;
    /******/
    /******/     // identity function for calling harmony imports with the correct context
    /******/     __webpack_require__.i = function(value) { return value; };
    /******/
    /******/     // define getter function for harmony exports
    /******/     __webpack_require__.d = function(exports, name, getter) {
    /******/         if(!__webpack_require__.o(exports, name)) {
    /******/             Object.defineProperty(exports, name, {
    /******/                 configurable: false,
    /******/                 enumerable: true,
    /******/                 get: getter
    /******/             });
    /******/         }
    /******/     };
    /******/
    /******/     // getDefaultExport function for compatibility with non-harmony modules
    /******/     __webpack_require__.n = function(module) {
    /******/         var getter = module && module.__esModule ?
    /******/             function getDefault() { return module['default']; } :
    /******/             function getModuleExports() { return module; };
    /******/         __webpack_require__.d(getter, 'a', getter);
    /******/         return getter;
    /******/     };
    /******/
    /******/     // Object.prototype.hasOwnProperty.call
    /******/     __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
    /******/
    /******/     // __webpack_public_path__
    /******/     __webpack_require__.p = "";
    /******/
    /******/     // Load entry module and return exports
    /******/     return __webpack_require__(__webpack_require__.s = 0);
    /******/ })
    /************************************************************************/
    /******/ ([
    /* 0 */
    /***/ (function(module, exports) {
    
    document.write('It works.')
    
    /***/ })
    /******/ ]);</script></body>
    </html>
    复制代码

    babel

      下面使用babel来进行es最新标准的代码向es5代码的转换,首先需要安装babel核心程序,及babel-loader

    npm install babel-loader babel-core 

      在使用babel-loader进行代码转换之前,要先了解到ecmascript标准变化很快,且浏览器支持情况不同。所以,出现了'es2015'、'es2016'、'es2017'、'latest'、'env(new)'等多个不同的标准。这时,要需要来选择从哪个标准进行转换,需要安装插件babel-preset-env 

    npm install babel-preset-env 

      在 webpack 配置对象中,需要添加 babel-loader 到 module 的 loaders 列表中

    复制代码
    //webpack.config.js
    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    
    module.exports = {
      entry: './src/app.js',
      output:{
        path: __dirname,//出口路径
        filename: 'js/[name].bundle.js'//出口名称
      },
      module:{
          loaders:[{
              test:/.js$/,
              use:{
                  loader:'babel-loader',
                  options:{
                      presets: ['env']
                  }
              }
          }]
      },
      plugins: [
        new HtmlWebpackPlugin({})
      ]
    }
    复制代码
    //app.js
    let num = 1;
    console.log(num);

    【打包速度】

      运行后,页面控制台输出1,转换正常。但是,babel的转换过程却很慢

      前面的博文webpack的四个基本概念,我们介绍过loader的test属性表示该loader必须满足的条件,上面代码中使用/.js$/ 来匹配,这样也许会去转译 node_modules 目录或者其他不需要的源代码。这样会大大增加webpack的编译时间

      要排除 node_modules,就要使用 loaders 配置的 exclude 选项,表示哪些除外,exclude:/node_modules/

      [注意]exclude也应该用正则的形式,如果用__dirname +'/node_modules'的形式则不会生效

    复制代码
    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    
    module.exports = {
      entry: './src/app.js',
      output:{
        path: __dirname,//出口路径
        filename: 'js/[name].bundle.js'//出口名称
      },
      module:{
          loaders:[{
              test:/.js$/,
              exclude: /node_modules/,
              use:{
                  loader: 'babel-loader',
                  options:{
                      presets: ['env']
                  }
              }
          }]
      },
      plugins: [
        new HtmlWebpackPlugin({})
      ]
    }
    复制代码

      当然了,除了exclude选项,也有include选项,能够明确被打包的文件时,使用include将使打包速度更快

      对于include来说,它比较特别,字符串形式__dirname + './src/'和正则形式/./src/都支持,经过测试,这两种形式的打包速度类似

    复制代码
    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    
    module.exports = {
      entry: './src/app.js',
      output:{
        path: __dirname,//出口路径
        filename: 'js/[name].bundle.js'//出口名称
      },
      module:{
          loaders:[{
              test:/.js$/,
              include:/./src/,
              use:{
                  loader: 'babel-loader',
                  options:{
                      presets: ['env']
                  }
              }
          }]
      },
      plugins: [
        new HtmlWebpackPlugin({})
      ]
    }
    复制代码

     

    CSS

      在webpack入门博文中由介绍过CSS插件的简单使用,接下来将详细介绍

      首先,要安装css-loader和style-loader,css-loader用于读取并加载css文件,style-loader将它插入到页面中

      [特别注意]在处理css时,最好不要使用include、exclude等属性。include、exclude属性是加快babel转换速度的,和css没什么关系,而且会添乱

    npm install css-loader style-loader
    复制代码
    //app.js
    require('./css/common.css');
    //common.css
    body{margin: 0;background-color: red}
    //webpack.config.js
    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    module.exports = {
      entry: './src/app.js',
      output:{
        path: __dirname,//出口路径
        filename: 'js/[name].bundle.js'//出口名称
      },
      module:{
          rules:[
              {
                  test:/.css$/,
                  use:[ 'style-loader', 'css-loader' ]
              }
          ]
      },
      plugins: [
        new HtmlWebpackPlugin({})
      ]
    }
    复制代码

      效果如下

    【自动前缀】

      页面加载CSS往往并不像上面的情况这么简单,需要处理很多问题,其中一个就是浏览器前缀问题。对于某些属性来说,比如transform,不同浏览器的版本对其支持程度不同,浏览器前缀也不同。这时,就需要能够根据实际情况,自动增加前缀,而postcss-loader就是这样的工具,而且功能要强大的多

      首先,先安装postcss-loader

    npm install postcss-loader

      然后,安装postcss的自动前缀的插件autoprefixer

    npm install autoprefixer

      配置如下

    复制代码
    //common.css
    body{transform: scale(0);background-color: red}
    //app.js
    require('./css/common.css');
    //webpack.config.js
    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    module.exports = {
      entry: './src/app.js',
      output:{
        path: __dirname,//出口路径
        filename: 'js/[name].bundle.js'//出口名称
      },
      module:{
          rules:[
              {
                  test:/.css$/,
                  use:[ 'style-loader', 
                        'css-loader',                    
                        {
                            loader: 'postcss-loader',
                            options: {plugins: [require('autoprefixer')]}            
                        }
                     ]
              }
          ]
      },
      plugins: [
        new HtmlWebpackPlugin({})
      ]
    }
    复制代码

      结果如下

      如果css文件中出现@import,则有两种处理方式,一种是将postcss文件单独写成配置文件postcss.config.js

    复制代码
    //common.css
    @import './flex.css';
    body{transform: scale(0);background-color: red}
    //flex.css
    body{display:flex;}
    //app.js
    require('./css/common.css');
    
    //webpack.config.js
    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    module.exports = {
      entry: './src/app.js',
      output:{
        path: __dirname,//出口路径
        filename: 'js/[name].bundle.js'//出口名称
      },
      module:{
          rules:[
              {
                  test:/.css$/,
                  use:[ 'style-loader', 
                      { loader: 'css-loader',
                        options: {importLoaders: 1} 
                      },
                    'postcss-loader'
                    ]
              }
          ]
      },
      plugins: [
        new HtmlWebpackPlugin({})
      ]
    }
    
    //postcss.config.js
    module.exports = {
     plugins:[require('autoprefixer')]
    }
    复制代码

      结果如下

      另一种需要安装postcss-import插件

    npm install postcss-import
    复制代码
    //common.css
    @import './flex.css';
    body{transform: scale(0);background-color: red}
    //flex.css
    body{display:flex;}
    //app.js
    require('./css/common.css');
    
    //webpack.config.js
    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    module.exports = {
      entry: './src/app.js',
      output:{
        path: __dirname,//出口路径
        filename: 'js/[name].bundle.js'//出口名称
      },
      module:{
          rules:[
              {
                  test:/.css$/,
                  use:[ 'style-loader', 
                      { loader: 'css-loader',
                        options: {importLoaders: 1 } 
                      },
                      {
                        loader: 'postcss-loader',
                        options: {plugins: [
                              require('postcss-import'),
                              require('autoprefixer')
                            ]
                        }     
                      }
                    ]
              }
          ]
      },
      plugins: [
        new HtmlWebpackPlugin({})
      ]
    }
    复制代码

      结果如下

    【sass】

      首先,需要安装sass-loader及node-sass

       [注意]关于node-sass安装的问题移步至此

    npm install sass-loader node-sass

      由于sass-loader中已经自带了关于@import处理的问题。所以,不需要css-loader及postcss-loader的额外处理

    复制代码
    //layer.scss
    @import './flex.scss';
    body{
        background-color:green;
        div{
             400px;
        }
    }
    //flex.scss
    .flex{display:flex;}
    //app.js
    require('./components/layer/layer.scss');
    
    //webpack.config.js
    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    module.exports = {
      entry: './src/app.js',
      output:{
        path: __dirname,//出口路径
        filename: 'js/[name].bundle.js'//出口名称
      },
      module:{
          rules:[
              {
                  test:/.scss$/,
                  use:[    'style-loader', 
                          'css-loader',
                        {
                            loader: 'postcss-loader',
                            options: {plugins: [require('autoprefixer')]}            
                        },
                        'sass-loader'
                     ]
              }
          ]
      },
      plugins: [
        new HtmlWebpackPlugin({})
      ]
    }
    复制代码

      结果如下

    【分离CSS】

      默认地,CSS作为模块资源被打包到入口js文件中。有时,需要把CSS文件分离出来,这时就需要用到extract-text-webpack-plugin插件

    npm install extract-text-webpack-plugin

      该插件的配置如下

    复制代码
    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    var ExtractTextPlugin = require('extract-text-webpack-plugin');
    module.exports = {
      entry: './src/app.js',
      output:{
        path: __dirname,//出口路径
        filename: 'js/[name].bundle.js'//出口名称
      },
      module:{
          rules:[
              {
                      test:/.scss$/,
                    use: ExtractTextPlugin.extract({
                      fallback: 'style-loader',
                      use:[ 'css-loader',
                            {
                                loader: 'postcss-loader',
                                options: {plugins: [require('autoprefixer')]}            
                            },
                            'sass-loader'
                         ]
                    })              
              }
          ]
      },
      plugins: [
        new HtmlWebpackPlugin({}),
        new ExtractTextPlugin("styles.css")
      ]
    }
    复制代码

      结果如下,该插件将入口文件中引用的 *.css,移动到独立分离的 CSS 文件。因此,你的样式将不再内嵌到 JS bundle 中,而是会放到一个单独的 CSS 文件(即 styles.css)当中。 如果样式文件大小较大,这会做更快提前加载,因为 CSS bundle 会跟 JS bundle 并行加载

    图片资源

      webpack在处理图片、音乐、电影等资源文件时,需要使用file-loader

    npm install file-loader

      默认情况下,使用file-loader生成的文件的文件名就是文件内容的MD5哈希值并保留原始扩展名

      以引入图片资源例,有以下几种情况

      1、通过css文件的background属性引入

    复制代码
    //webpack.config.js
    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    module.exports = {
      entry: './entry.js', //入口文件
      output: {
        path: __dirname,//出口路径
        filename: 'js/[id]-[name]-[hash].js'//出口名称
      },
      module:{
    
          rules:[
              {
                  test:/.css$/,
                  use:[ 'style-loader', 'css-loader' ]
              },
              {
                  test:/.(png|jpg|gif|svg)$/i,
                  use:'file-loader'
              }
          ]
      },  
      plugins: [
        new HtmlWebpackPlugin()
      ]
    }
    //entry.js
    require('./src/css/common.css');
    //common.css
    body{background: url('../img/eg_bulbon.gif')}
    复制代码

      结果如下

      2、通过模板html文件img标签引入,这时需要使用${require('')}将相对路径包裹一次

    复制代码
    //webpack.config.js
    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    module.exports = {
      entry: './entry.js', //入口文件
      output: {
        path: __dirname,//出口路径
        filename: 'js/[id]-[name]-[hash].js'//出口名称
      },
      module:{
          rules:[
              {
                  test:/.css$/,
                  use:[ 'style-loader', 'css-loader' ]
              },
              {
                  test:/.(png|jpg|gif|svg)$/i,
                  use:'file-loader'
              }
          ]
      },  
      plugins: [
        new HtmlWebpackPlugin({
            template:'template/template.html'
        })
      ]
    }
    //template.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
    <img src="${require('../src/img/eg_bulbon.gif')}" alt="">
    </body>
    </html>
    复制代码

      结果如下

      3、若模板使用ejs-compiled-loader插件,则无法使用${require('')}语句,需要使用HtmlWebpackPlugin传参来构造绝对路径

    复制代码
    //webpack.config.js
    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    module.exports = {
      entry: './entry.js', //入口文件
      output: {
        path: __dirname + '/dist',//出口路径
        filename: 'js/[id]-[name]-[hash].js'//出口名称
      },
      module:{
          rules:[
              {
                  test:/.css$/,
                  use:[ 'style-loader', 'css-loader' ]
              },
              {
                  test:/.(png|jpg|gif|svg)$/i,
                  use:'file-loader'
              }
          ]
      },  
      plugins: [
        new HtmlWebpackPlugin({
            template:'ejs-compiled-loader!template/template.html',
            file:__dirname
        })
      ]
    }
    //template.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
    <div>
        <% include  template/header.html %>
    </div>
    </body>
    </html>
    //header.html
    <img src="<%=htmlWebpackPlugin.options.file%>srcimgeg_bulbon.gif" alt="">
    复制代码

      结果如下

    【file-loader参数】

      文件名模板占位符有如下几种

    复制代码
    [ext] 资源扩展名
    [name] 资源的基本名称
    [path] 资源相对于 context 查询参数或者配置的路径
    [hash] 内容的哈希值,默认为十六进制编码的 md5
    [<hashType>:hash:<digestType>:<length>] 可选配置
      其他的 hashType, 即 sha1, md5, sha256, sha512
      其他的 digestType, 即 hex, base26, base32, base36, base49, base52, base58, base62, base64
      length 字符的长度
    [N] 当前文件名按照查询参数 regExp 匹配后获得到第 N 个匹配结果
    复制代码
    复制代码
    {
      test:/.(png|jpg|gif|svg)$/i,
      use:[{
                  loader:'file-loader',
                options: {
                    name:'[name]-[hash:5].[ext]'
                }  
            }]
    }
    复制代码

      或者

    {
      test:/.(png|jpg|gif|svg)$/i,
      use:['file-loader?name=[name]-[hash:5].[ext]']
    }

      结果如下

    【url-loader】

      url-loader功能类似于file-loader,但是在文件大小(单位byte)低于指定的限制时,可以返回一个dataURL

      可以通过传递查询参数(query parameter)来指定限制(默认为不限制)。

      如果文件大小超过限制,将转为使用 file-loader,所有的查询参数也会传过去

    npm install url-loader

      图片的大小为1.1kb,下面将限制设置为2000,则图片将以base64格式传递

    {
      test:/.(png|jpg|gif|svg)$/i,
      use:['url-loader?limit=2000']
    }

      结果如下

      如果将限制大小设置为1000,图片以src的形式传递

    复制代码
    {
      test:/.(png|jpg|gif|svg)$/i,
      use:[{
                  loader:'url-loader',
                options: {
                    limit:1000,
                    name:'[name]-[hash:5].[ext]'
                }  
            }]
    }
    复制代码

    【image-webpack-loader】

      使用image-webpack-loader来压缩图片

    npm install image-webpack-loader

      插件一张大小为4.1kb的名称为'm.jpg'的图片,配置如下

    复制代码
    {
      test:/.(png|jpg|gif|svg)$/i,
      use:[
        'url-loader?limit=1000&name=[name]-[hash:5].[ext]',
        'image-webpack-loader'
      ]
    }
    复制代码

      结果如下所示,生成大小为3.28kb,名称为'm-c7083.jpg'的图片

    实用配置

      下面将使用webpack搭建一个实用的开发环境

    复制代码
    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    var ExtractTextPlugin = require('extract-text-webpack-plugin');
    module.exports = {
        entry: './src/app.js',//入口文件
        output:{
            path: __dirname,//出口路径
            filename: 'js/[name].bundle.js'//出口名称
        },
        module:{
            rules:[
                {
                    test:/.scss$/,
                    use: ExtractTextPlugin.extract({
                        fallback: 'style-loader',
                         use:[ 
                                 'css-loader',
                                {
                                    loader: 'postcss-loader',
                                    //自动添加前缀
                                    options: {plugins: [require('autoprefixer')]}            
                                },
                                'sass-loader'
                            ]
                    })              
                },
                {
                    test:/.js$/,
                    include:/./src/,
                    use:{
                            loader: 'babel-loader',
                            //将最新标准的js代码翻译为es5代码
                            options:{presets: ['env']}
                        }
                },
                {
                    test:/.(png|jpg|gif|svg)$/i,
                    use:[
                            //当图片大小大于1000byte时,以[name]-[hash:5].[ext]的形式输出
                            //当图片大小小于1000byte时,以baseURL的形式输出
                            'url-loader?limit=1000&name=[name]-[hash:5].[ext]',
                            //压缩图片
                            'image-webpack-loader'
                        ]
                }
              ]
        },
        plugins: [
              //使用模板生成html文件
            new HtmlWebpackPlugin({template:'ejs-compiled-loader!template/template.html'}),
            //分离出css到style.css
            new ExtractTextPlugin("style.css")
        ]
    }

  • 相关阅读:
    表格边框
    vue路由守卫
    移动端专用css
    原生js写的的浏览器历史记录
    有趣
    表格边框
    路由
    php安装
    curl
    case when
  • 原文地址:https://www.cnblogs.com/libin-1/p/7030415.html
Copyright © 2011-2022 走看看