webpack2进阶之多文件,DLL,以及webpack-merge

   2023-02-08 学习力0
核心提示:本需要对webpack已有一定的了解,如果你没接触过webpack或者刚刚接触webpack,可以考虑先看一下我的这篇教程。入门教程##1.打包多文件之前,当需要打包多个而文件时,我是这么写的:```javascriptmodule.exports={entry:{"page/main/main":'./src/js/index.js

本需要对webpack已有一定的了解,如果你没接触过webpack或者刚刚接触webpack,可以考虑先看一下我的这篇教程。



##1.打包多文件 之前,当需要打包多个而文件时,我是这么写的: ```javascript module.exports={ entry:{ "page/main/main":'./src/js/index.js', "page/car/car":"./src/js/car.js", "page/goods/goods":"./src/js/goods.js", }, output:{ filename:"[name].[hash].js", path:path.resolve(__dirname,'dist') }, 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"] }) ] ```

可以发现,我们在entry中手动引入了多个文件; 在plugins中,我们又手动的多次new htmlWebpackPlugin()。

虽然能够正常的运行,然而存在很多限制。

  • 首先:存在大量重复的代码。现在只有3个页面,假如现有10个页面,那么你就得手动的new10次,在enrty中输入10个入口。

  • 其次:当增加新的页面时,又得过来webpack的配置里面手动的再加入到入口文件中。

明显的,对于这些重复的而且长得很像的,如果能自动获取到需要配置的文件,并且在一个循环里面调用,那就方便多了。

使用node.js的golb模块来获取文件

//引入glob
var glob= require('glob');

//同步读取src目录下所有的html文件
var files = glob.sync('./src/*.html');
var entry={};
var plugins=[];

//循环将文件
files.forEach(function(item,i){
    //item类似:./src/index.html

    var htmlName=item.slice(item.lastIndexOf("/")+1);
    //最后生成的文件名只需要最后面的名字index.html
    
    var name=htmlName.split(".")[0];

    //添加到entry入口,并制定生成文件的目录
    entry["page/"+name+"/"+name]='./src/js/'+name+'.js'

    //生成htmlWebpackPlugin实例
    plugins.push(
        new htmlWebpackPlugin({
            template:item,
            filename:htmlName,
            chunks:["page/"+name+"/"+name]
        })
    )
});

module.exports={
    entry:entry,
    output:{
        filename:"[name].[chunkhash].js",
        path:path.resolve(__dirname,'dist'),
  },
 

  module:{
    rules:[
          {
              test: /\.js$/,
              exclude: /node_modules/,
              use: {
                loader: 'babel-loader'          
            }
        },  
    ]
  },
  plugins:plugins
}

可以发现,使用glob.sync来读取文件并进行循环操作,原本需要手动操作的部分,循环已经帮我们处理好了。原本需要很多new new htmlWebpackPlugin()已经不再存在,而且即使后续需要添加新的页面,也不需要我们手动去添加,glob.sync会自己去读取所有的*.html文件,接着循环会帮我们处理。

这里需要注意的地方就是,index.html对应的js文件必须为index.js,ceshi.html文件对应的文件必须为ceshi.js。至于js里面需要引入其他库,或者自己写的工具函数,哪个页面需要,只需引入即可,webpack会自己处理好。

2.使用DLL提取公共库


当页面存在引用相同的库时,最好还是将这些库文件提取到单独的文件,页面只保留业务逻辑的js代码。
为了提取文件,有2中处理方案:
  • 使用CommonsChunkPlugin来提取

在上面的代码上增加:(以下这部分代码只在使用CommonsChunkPlugin时需要)

  entry.vendor=[
     //举例如下:
     "vue","vuex","axios","jquery","vue-router","moment","lodash"
  ];

  plugins=[   
     new webpack.optimize.CommonsChunkPlugin({
         name:["vendor","manifest"]
       })
  ]

  //修改循环中的chunks, 增加vendor以及manifest:
  files.forEach(function(item,i){
      plugins.push(
          new htmlWebpackPlugin({
              template:item,
              filename:htmlName,
              chunks:["page/"+name+"/"+name,"vendor","mainfest"]
          })
      )
  });

再执行webpack,可以发现公共的库已经被提取到单独的vendor文件。

  • 使用DLL

对于 CommonsChunkPlugin,webpack 每次打包实际还是需要去处理这些第三方库,只是打包完之后,能把第三方库和我们自己的代码分开。

DLLPlugin 则是能把第三方代码完全分离开,即每次只打包项目自身的代码。

这里我使用的是autodll-webpack-plugin。

//安装模块
npm install --save-dev autodll-webpack-plugin

//引入模块
var AutoDllPlugin = require('autodll-webpack-plugin');

在plugins中添加插件:(需要放在循环之前,防止数组被重新赋值)
var plugins=[
  new AutoDllPlugin({
        //文件名
        filename: '[name].[hash].js', 

        //打包后的文件路径
        path: './page/common/',

        //是否将生成的Js文件注入到html文件中
        inject:true,

        //需要分离的库
        entry: {
          vendor: [
            "vue","vuex","axios","jquery","vue-router","moment","lodash","vue-touch","vue-lazyload"
          ]
        },

        //压缩代码(注意这里是压缩分离出来的库文件代码,跟外面的要区分开来,如果外面的需要压缩,外面的plugins中也需要new一个压缩实例)
        plugins: [
          new webpack.optimize.UglifyJsPlugin()
        ]
      })
] 

执行webpack命令,可以发现公共的库文件也被打包到单独的文件了。

autodll-webpack-plugin在内存中缓存了文件,所以当你第二此执行webpack命令进行打包时,可以明显发现打包时间少了很多。

CommonsChunkPlugin每次都全部重新打包再进行分离,所以当需要多次修改文件时,autodll-webpack-plugin可以明显降低打包的时间,尤其是依赖很多外部库的时候。

3.使用webpack-merge区分生成环境和开发环境:


很多时候,我们都需要针对不同的环境进行不用的操作。

比如在生成环境下分离css到单独文件:
var extractSass = new ExtractTextPlugin({
    filename: "[name].[contenthash].css",
    disable: process.env.NODE_ENV === "development"
});
在生成环境下要压缩代码:

new UglifyJSPlugin();

在开发环境下使用代理
devServer:{
   proxy: {
      'api': {
          target: 'http://api.douban.com/v2/movie/',
          secure: false,
          changeOrigin: true
      }
  }

通常会用process.env.NODE_ENV === "development",并且在package.json中设置环境变量来进行判断,不过当文件大了或者页面需要判断的地方多了之后,配置文件就会充斥着大量三元表达式

可以考虑用webpack-merge将配置文件拆分为3个文件,一个是webpack.common.js,即不管是生产环境还是开发环境都会用到的部分,以及webpack.product.js和webpack.dev.js, 并且使用webpack-merge来合并对象。

common.js

 //webpack.common.js
 var path = require('path');
 var HtmlWebpackPlugin = require('html-webpack-plugin');

 module.exports = {
     entry: {
         app: './src/index.js'
     },
     output: {
         filename: '[name].bundle.js',
         path: path.resolve(__dirname, 'dist')
     },
     module: {
        rules:[
            {
                 test: /\.js$/,
                 exclude: /node_modules/,
                 use: {
                     loader: 'babel-loader'
                 }
            },
        ]           
     },
    plugins: [
         new HtmlWebpackPlugin({
             title: 'test'
         })
     ],
 }

dev.js

//开发环境webpack.dev.js
var merge = require('webpack-merge');
var common = require('./webpack.common.js');

module.exports = merge(common, {
  module:{
     rules:[
       {
           test: /\.css$/,
           use:["style-loader","css-loader"]
       }
   ]      
 },
  devtool: 'inline-source-map',
  devServer:{
       open:true,  
       hot: true, 
       proxy: {
          '/api/': {
              target: 'http://baidu.com',
              secure: false,
              changeOrigin: true
          }
      }      
    },
})

product.js

//生产环境webpack.product.js
var merge = require('webpack-merge');
var UglifyJSPlugin = require('uglifyjs-webpack-plugin');
var common = require('./webpack.common.js');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var cleanPlugin = require("clean-webpack-plugin");
var extractSass = new ExtractTextPlugin({
    filename: "[name].[contenthash].css",
});

module.exports = merge(common, {
    module: {
        rules: [{
            test: /\.css$/,
            use: extractSass.extract({
                use: [{
                    loader: "css-loader"
                }, ],
                fallback: "style-loader"
            })
        }]

    },
    devtool: 'source-map',
    plugins: [
        new cleanPlugin(["dist"]),
        new UglifyJSPlugin(),
        extractSass,
    ]
});
在packjson中修改webpack默认配置文件
"scripts": {
    "dev": "webpack-dev-server --config webpack.dev.js",
    "build": "webpack --config webpack.product.js"
}

通过npm run dev以及npm run build来执行对应的操作。

以上只是一个简单的示例,并不是一定需要拆分成3个文件,如果你的配置足够简单,写成一个webpack.config.js足以。但是,假如你的项目足够庞大,最好还是拆开来写,可以参考vue-cli的脚手架的配置。

 
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • webpack命令局部运行的几种方法 webpack用法
    webpack命令局部运行的几种方法 1. 第一种,先全局安装webpack命令:npm install -g webpack然后再在项目内安装命令:npm install webpack --save-dev这样在项目内就可以直接使用webpack命令了,运行的却是局部的webpack 2.第二种,直接在局部安装webpack,
    03-08
  • 扩大编译内存 webpack-dev-server --inline --p
     verbose stack Error: choreographer@1.0.0 rundev: `webpack-dev-server --inline --progress --config build/webpack.dev.conf.js`扩大编译内存 地址  D:\park\node_modules\.bin\webpack-dev-server.cmd@ECHO offSETLOCALCALL :find_dp0IF EXIST "%dp0
    03-08
  • Webpack的安装与使用 webpack安装配置
    Webpack的安装与使用 webpack安装配置
    webpack 常用安装命令webpack 安装及删除命令:npm/cnpm install webpack -g (全局安装)npm/cnpm uninstall webpack -g (全局卸载)npm/cnpm install webpack -s (局部安装)npm/cnpm uninstall webpack -s (局部卸载)安装时,加上 '--save' 安装写在 package.j
    03-08
  • html-webpack-plugin不输出script标签的方法 ht
    约550行:if (!this.options.disableScript) {if (this.options.inject === 'head') {head = head.concat(scripts);} else {body = body.concat(scripts);}}然后这样使用:new HtmlWebpackPlugin({disableScript: true,//...})
    03-08
  • gulp与webpack-stream集成配置 grunt gulp webp
    webpack非常强大,但是也有不足的地方,批量式处理依然是gulp更胜一筹.我们是否可以将两者的优点结合起来呢? 这篇文章就是讲述如何集成gulp和webpack1.安装webpack-stream很重要的插件,当然也可以直接使用官方的webpack,集成方式可以看webpack官网. 但webpack-s
    03-08
  • 【原创】从零开始搭建Electron+Vue+Webpack项目框架(三)Electron+vue+webpack联合调试
    【原创】从零开始搭建Electron+Vue+Webpack项目
    导航:(一)Electron跑起来(二)从零搭建Vue全家桶+webpack项目框架(三)Electron+Vue+Webpack,联合调试整个项目(四)Electron配置润色(五)预加载及自动更新(六)构建、发布整个项目(包括client和web)摘要:前面两篇介绍了如何启动Electron和Vue项
    03-08
  • 【Vue】WebPack 忽略指定文件或目录
    前端Vue项目使用 WebPack 打包时,有时候我们需要忽略掉一些文件。比如一些说明文档、ReadMe之类的,我们只希望它存在于源码中,而不是被打包给用户。通过修改 webpack.base.conf.js 配置文件,有以下方式可以达到目的。方法1:使用 null-loadermodule: {rule
    03-08
  • Karma 4 - Karma 集成 Webpack 进行单元测试
     可以将 karma 与 webpack 结合起来,自动化整个单元测试过程。1. 首先根据 1 完成基本的 karma 测试环境。2. 安装 webpack 和 webpack 使用的 loader在最简单的情况下,我们只需要 webpack 和 webpack 的 karma 插件 karma-webpacknpm i -D webpack karma-w
    03-08
  • 前端工具之webpack webapp前端
    前端工具之webpack webapp前端
    1webpack简介:2webpack的使用步骤  1全局安装:webpack和webpack-cli      2创建一个文件夹命名webpack01,项目初始化:(一路enter键即可)      3本地项目安装webpack     4 
    03-08
  • 手把手教你webpack、react和node.js环境配置(上篇)
    手把手教你webpack、react和node.js环境配置(
    很多人刚学习react的时候,往往因为繁琐的配置而头疼,这里我将手把手教大家怎么用webpack配置react和redux的环境,这篇教程包括前端react和后台node整个网站的环境配置,对node没兴趣的可以只看这篇。这里是下篇链接:手把手教你webpack、react和node.js环境
    03-08
点击排行