带你由浅入深探索webpack4(一)

 相信你或多或少也据说过webpack、gulp等这些前端构建工具。近年来webpack愈来愈火,能够说成为了前端开发者必备的工具。若是你有接触过vue或者react项目,我想你应该对它有所了解。css

这几天我从新整理了一下webpack中知识点,把一些经常使用到的总结出来,但愿能帮助到你们以及加深本身对webpack的理解。html

(因为我在写这篇文章的时候webpack最新版本是4.3 若是某些配置有变动,请自行查看官方最新文档。千万别看中文文档,坑太多了更新太慢,不少属性都被弃用了,要看直接看英文的。)前端

 

一: 初识webpackvue

1.1 什么是webpack?node

这个我直接引用官方文档的介绍:react

Webpack 是当下最热门的前端资源模块化 管理和打包 工具。它能够将许多松散的模块按照依赖和规则打包成符合生产环境部署的前端资源。还能够将按需加载的模块进行代码分割,等到实际须要的时候再异步加载。webpack

在这里我就很少介绍了,百度一搜一大堆介绍,本文章主要是介绍webpack怎么用。es6

 

1.2 安装webpackweb

由于webpack是基于nodejs实现的,因此要安装webpack,先得安装nodechrome

nodejs的中文网址:http://nodejs.cn/

下载完node以后,直接傻瓜式安装就好,接着,咱们打开命令行,看下node和vue的版本

当输出版本号时,证实安装成功。(建议node尽可能8.0版本以上 npm尽可能6.0版本以上)。

这里我比较建议用淘宝的镜像cnpm,npm在国内实在是太慢了。

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

固然,若是你网速快的话,用npm命令也不要紧。

首先,咱们建立一个空的文件夹,就起名叫webpack吧,而后执行一下初始化命令

npm init -y

接着安装webpack和webpack-cli(建议局部安装,全局安装webpack可能会致使webpack版本不一样而没法正常使用)

npm install webpack webpack-cli --save-dev 或者 cnpm install webpack webpack-cli -save-dev

 

 

1.3 webpack的初始化配置

首先咱们在本件的一级目录下建立一个src文件,src文件夹内再建立一个inde.js文件和一个index.html文件

src/html:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>初始化配置</title>
</head>
<body>
<div id="root">hello word!</div>
<script src="index.js"></script>
</body>
</html>
 

src/js:

var root = document.getElementById('root');
var text = document.createElement('div');
text.innerText = "斌果欢迎你!"
root.append(text);

固然packagej.json文件也要配置一下。

删除“main”入口配置添加"private"为true

{
  "name": "webpack",
  "version": "1.0.0",
  "description": "",
  "private":true,
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^4.30.0",
    "webpack-cli": "^3.3.0"
  }
}

这样作主要是为了让你的项目私有化,防止意外发布你的代码。

接着,在一级目录下再建立一个 webpack.config.js  这个主要是webpack的配置文件

webpack.config.js

const path = require('path');

module.exports = {
    entry:'./src/index.js',  //打包文件的入口
    output:{                 //打包文件的出口
        filename:'bundle.js',          //打包后的文件名
        path:path.resolve(__dirname,'dist')      //打包后文件存放的位置
    }
}

webpack使用的是common.js规范的语法,在webpack.config.js中设置了webpack打包的基本配置。

接着咱们在控制台中直接运行

npx webpack

 再回到项目中的,发现多了一个dist文件夹。里面有一个打包后的bundle.js文件,就这样咱们就将这个简单的项目打包成功了。

你或许会问npx是什么,我怎么历来没有用过,可能你一直都是在用npm run **  npx其实就是直接运行node_modules中的配置

固然你也能够在package.json中配置一下,像这样

配置以后你运用npm run bundle 效果其实和运行 npx webpack是同样,其最终仍是运行npx webpack的命令.。

 

1.4 webpack的初次使用

在上一小节,你可能会以为,这webpack打包完后好像也并无用,到底webpack是用来干吗的?这一小节,就带你用用webpak。

继续上一节,咱们在src下继续建立header.js,connent.js、footer.js这三个文件.。

src/header.js

var root = document.getElementById('root');
var text = document.createElement('div');
text.innerText = "头部内容"
root.append(text);

src/content.js

var root = document.getElementById('root');
var text = document.createElement('div');
text.innerText = "中部内容"
root.append(text);

src/footer.js

var root = document.getElementById('root');
var text = document.createElement('div');
text.innerText = "尾部内容"
root.append(text);

若是咱们想将这三个js同时引入到index.html咱们就必需要这样写

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>简单实例</title>
</head>
<body>
    <div id="root">hello word!</div>
    <script src="header.js"></script>
    <script src="content.js"></script> 
    <script src="footer.js"></script>
</body>
</html>

这样咱们要引入3个js  对性能的消耗是十分巨大的 ,加入有100个这样的js文件,那咱们不就要引入100个js?  因而咱们想能够能够只引入一个inde.js。就像下面那样:

咱们将src中引入的header、content、footer、index所有使用esModule语法以下

function header(){
    var root = document.getElementById('root');
    var text = document.createElement('div');
    text.innerText = "头部内容"
    root.append(text);
}
export default header;
import header from './header'
import content from './content'
import footer from './footer'

header();
content();
footer();

当咱们打开html,就会发现报了个错!

这是为何呢?  由于浏览器根本都不认识import是什么,是不认识es、common这些语言的,可是,webpack认识啊!

咱们直接运行     npx webpack

而后咱们index.html中直接引入打包后的bundle.js,就会神奇的发现他成功运行并且没报错。

由于webpack已经帮咱们将esModule语法转化为浏览器能识别的法语告诉浏览器我要引入这三个js。

 

 

 

2、webpack的核心经常使用配置

 

2.1 HtmlWebpackPlugin

在上一章能够看到,当咱们打包完成后,要本身将打包后的js代码引入到html文件中,这显得不那么智能。

HtmlWebpackPlugin插件作得工做就是在打包完成后,自动生成一个html文件,并将打包生成的js自动引入到html文件中。

首先安装这个插件:  npm install html-webpack-plugin -D

安装完成后,咱们须要在webpack.config.js中配置一下:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');  //++++导入插件

module.exports = {
    entry:'./src/index.js',  //打包文件的入口
    plugins:[
        new HtmlWebpackPlugin({
            template: 'src/index.html'   //++++其会根据该html文件做模板自动导入打包后的js ,然
        })                               //++++后将生成的html放到出口文件夹中
    ],                             
    output:{                 //打包文件的出口
        filename:'bundle.js',          //打包后的文件名
        path:path.resolve(__dirname,'dist')      //打包后文件存放的位置
    }
}

这样的话就无须要咱们本身配置html  其会在出口文件夹自动生成打包后的html。

运行npx webpack后

=>

 

 

2.2 CleanWebpackPlugin

当咱们每次打包完文件后,都会生成一个新的dist文件覆盖上一个dist文件,但若是上个dist中有一些其余的文件没有被覆盖掉,就会成为杂鱼,当咱们屡次打包后,杂鱼可能就会变得愈来愈多,严重影响开发。

CleanWebpackPlugin插件作得就是每次打包时都会删除上一次打包的文件,而不是覆盖,这就使得每一次打包后的文件都是崭新的,而不会混合上一次遗留的文件。

首先安装这个插件: npm install clean-webpack-plugin -D

接着配置一下webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');  //++++导入插件

module.exports = {
    entry:'./src/index.js',  //打包文件的入口
    plugins:[
        new HtmlWebpackPlugin({
            template: 'src/index.html'   //其会根据该html文件做模板自动导入打包后的js ,然
        }),                             //后将生成的html放到出口文件夹中
        new CleanWebpackPlugin()    //++++配置删除的文件                              
    ],                             
    output:{                 //打包文件的出口
        filename:'bundle.js',          //打包后的文件名
        path:path.resolve(__dirname,'dist')      //打包后文件存放的位置
    }
}

运行npx webpack 后

 =>

 

 

 2.3 Mode配置

当咱们每次打包的时候都会提示以下警告 

这究竟是什么呢? 其实就是叫咱们设置工做状态,既mode

mode有两种状态,主要是用于代表当前开发状态!

development: 开发模式    打包后代码没有被压缩

production:    生产模式     打包后代码被压缩为一行

 

 

2.4 SourceMap配置

当咱们的代码报错时,调试工具显示的是打包后js的报错行数,这样咱们很难找到原代码到底在哪报错。

SourceMap主要用于开发模式下使用,其能展示出打包后文件与源文件的映射关系。

这究竟是怎么用的呢? 查看下官方文档能够看到有这么多参数,不急,慢慢来解释:

 

+表示性能较好,-表示性能较差  eval、inline、cheap、module等能够自由组合使用

none:不产生映射,速度最快。

eval:执行速度也很快,性能最好,当时代码提示不全面。

source-map:  把映射文件生成到独立的文件,通常不建议使用,打包速度过慢。

-inline-: 不单独生成文件,将生成的映射文件以base64的格式插入到打包后的js文件中,精确显示错误位置

-cheap-:代码只显示出错代码在第几行,不精确显示具体位置,有效提升打包效率。

-module-:不只提示本身的业务代码是否出错,还提示第三方模块中的代码是否出错。

在开发环境中,建议使用:cheap-module-eval-source-map 

在生产环境中,上线代码通常不设置devtool。若是想知道报错位置,建议使用:cheap-module-source-map

由于咱们主要在开发环境下,因此咱们使用cheap-module-eval-source-map

 

 

 2.5资源管理配置

2.5.1 加载css、sass、css前缀

首先咱们先在src下建立一个index.css

src/index.css:

body{
    background-color: blue;
}

接着咱们在src中的index.js中导入css文件

src/index.js:

import header from './header'
import content from './content'
import footer from './footer'
import './index.css'    //+++引入css文件

header();
content();
footer();

因为webpack是没法识别以css后缀的文件,因此咱们要引入loader(翻译官)帮咱们解析css.

咱们须要安装一下loader:  npm install style-loader css-loader --save-dev

安装完成后,咱们还须要在webpack.config.js中配置一下:

webpack.config.js:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');  //导入插件

module.exports = {
    mode:'development',
    devtool:'cheap-module-eval-source-map',   //+++映射
    entry:'./src/index.js',  //打包文件的入口
    module:{
        rules:[
            {
                test:/\.css$/,       //+++配置以css结尾的文件  
                use:[                //+++添加翻译官,顺序为由下向上,由右向左
                    'style-loader',
                    'css-loader'
                ]
            }          
        ]
    },
    plugins:[
        new HtmlWebpackPlugin({
            template: 'src/index.html'   //其会根据该html文件做模板自动导入打包后的js ,然
        }),                             //后将生成的html放到出口文件夹中
        new CleanWebpackPlugin()    //配置删除的文件                              
    ],                             
    output:{                 //打包文件的出口
        filename:'bundle.js',          //打包后的文件名
        path:path.resolve(__dirname,'dist')      //打包后文件存放的位置
    }
}

因为css翻译官解析后webpack仍是不认识css文件,还须要使用style翻译官去处理一下才能被webpack所解析。

运行npx webpack打包后,咱们直接打开dist下的index.html文件,就能够看到css文件已经被成功引入.

加载sass也是相似,只须要添加一个sass-loader、node-sass就能够了!在这里就不加演示。

{
                test:/\.scss$/,
                use:[
                    'style-loader',
                    'css-loader',
                    'sass-loader'
                ]
            }        

而加前缀的话,在不一样浏览器前缀各有不一样。

  • Trident内核:主要表明为IE浏览器, 前缀为-ms
  • Gecko内核:主要表明为Firefox, 前缀为-moz
  • Presto内核:主要表明为Opera, 前缀为-o
  • Webkit内核:产要表明为Chrome和Safari, 前缀为-webkit

在这里咱们只须要引入postcss-loader和autoprefixer就能够了

安装一下 : npm install postcss-loader autoprefixer --save-dev

在根目录下建立一个postcss.config.js文件

postcss.config.js:

module.exports = {
    plugins:[
        require('autoprefixer')
    ]
}

接着在webpack.config.js修改一下loader

           {
                test:/\.css$/,       //配置以css结尾的文件  
                use:[                //添加翻译官,顺序为由下向上,由右向左
                    'style-loader',
                    'css-loader',
                    'postcss-loader'       //+++配置前缀
                ]
            },
            {
                test:/\.scss$/,
                use:[
                    'style-loader',
                    'css-loader',
                    'sass-loader',   //配置sass翻译官
                    'postcss-loader'   //+++配置前缀
                ]
            }      

可是若是咱们要在sass中再引入sass 这就会出错,由于再引入的sass文件没有通过翻译官翻译.

因此,咱们还须要配置一下sass

           {
                test:/\.scss$/,
                use:[
                    'style-loader',
                    {
                        loader:'css-loader',
                        options:{
                            importLoader:2,//+++若是sass文件还引入其余sass,另外一个会从新从下向上开始解析
                            modules:true //+++开启css模块打包
                        }
                    },
                    'sass-loader',          //配置sass翻译官
                    'postcss-loader'        //配置前缀
                ]
            }   

2.5.2 加载图片、字体

加载图片主要使用两个loader分别为 file-loader  url-loader

其两个loader都是解析图片。不过url-loader能够将小图片转化成base64的格式存放到打包后的css中

咱们通常都是使用url-loader 这样处理小图片的时候就能够更快加载而无需引用原图片地址。

安装: npm install url-loader file-loader -D

配置:

webpack.config.js:

          {
                test:/\.(png|jpg|gif|svg)$/,
                use:[
                    {
                        loader:'url-loader',
                        options:{
                            name:'[name].[ext]',
                            outputPath:'images/',
                            limit:8096  //+++小于4K的图片转化为base64存放到打包后的js中
                        }
                    }
                ]

            }        

由于file-loader和url-loader能够加载任何文件,因此咱们也能够用其来加载字体文件

webpack.config.js:

           {
                test:/\.(woff|woff2|eot|ttf|otf)&/,
                use:[
                    'file-loader'
                ]

            }

 2.5.3加载es6语法

因为不少低版本的浏览器都不支持ES6语法,因此,咱们须要将ES6语言转换为ES5的语法。

在之前我都是用babel-preset-es2015转换的,如今官方推荐使用babel-preset-env转换,咱们就使用官方推荐的来转换吧.

因为babel只转换语法,须要使用babel-polyfill来支持新语法像promise这些。

首先咱们先安装依赖  npm install babel-loader @babel/core babel-preset-env @babel/polyfill -D

接着咱们在webpack.config.js中配置一下

webpack.config.js:

{
                test: /\.js$/,
                exclude: /node_modules/,//不须要对第三方模块进行转换,耗费性能
                use:[
                    'babel-loader'
                ] 
       

            },

由于bebel配置的信息太多了,咱们能够在根目录下建立一个.babelrc文件

.babelrc:

{
    "presets": [
        [
            "babel-preset-env", {         
                "targets": {         //在这些版本以上的浏览器中不转换为es5
                    "chrome": "67",
                    "firfox":"60",
                    "edge":"17",
                    "safari":"11.1"
                },
                "useBuiltIns": "usage"
            }
        ]
    ]
}

最后咱们还须要在index.js中引入polyfill:

src/index.js:

import "@babel/polyfill";

可是若是在第三方模块时使用@babel/polyfill会污染全局变量,因此咱们可使用runtime-transform插件

其与polifill相似,但不会污染全局变量其用法和上面差很少

咱们安装一下:

npm install babel-runtime babel-plugin-transform-runtime -D

在.babelrc中添加配置就能够了。

{
    "plugins": ["transform-runtime"]
}

更多的配置能够参考官网文档:babeljs.io/setup

 

 

2.6配置多个出入口文件

在目前,咱们一直以一个index.js为入口,bundle.js文件为出口,但随着程序的增长,咱们可能须要输出多个bundle文件。

这个很简单,咱们新建一个print.js文件,并添加一些逻辑

import Header from './header'

Header();
console.log('这是打包的第二入口文件');

而后咱们只须要修改一下webpack.config.js中的出入口配置就能够了。

webpack.config.js:

 entry:{
        main:'./src/index.js',       //打包入口文件
        print:'./src/print.js'
    },
......
 output:{
       filename:'[name].js',          //打包后的文件名
        path:path.resolve(__dirname,'dist')      //打包后文件存放的位置
     }

 

 

2.7热更新配置

咱们每次打包的时候,都须要手动运行npm run bundle 或者npx webpack这显得什么繁琐。

下面介绍几个配置,能够在代码发生变化后自动编译代码。

2.7.1观察模式watch

咱们只须要在package.json文件中添加一个用于启动观察模式的npm script脚本就能够了;

{
  "name": "webpack",
  "version": "1.0.0",
  "description": "",
  "private": true,
  "scripts": {
    "bundle": "webpack",
    "watch": "webpack --watch"    //+++添加启动脚本
  },
   "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "autoprefixer": "^9.5.1",
    "clean-webpack-plugin": "^2.0.1",
    "css-loader": "^2.1.1",
    "file-loader": "^3.0.1",
    "html-webpack-plugin": "^3.2.0",
    "node-sass": "^4.11.0",
    "postcss-loader": "^3.0.0",
    "sass-loader": "^7.1.0",
    "style-loader": "^0.23.1",
    "url-loader": "^1.1.2",
    "webpack": "^4.30.0",
    "webpack-cli": "^3.3.0"
  }
}

这样当咱们修改js中的代码时,其会自动执行打包,咱们只须要刷新一下页面就能够看到变化。

2.7.2使用webpack-dev-server

当咱们使用watch时,咱们虽然能够自动打包,可是页面不能自动刷新,须要咱们手动刷新。

webpack-dev-server为咱们提供了一个简单的web服务器,可以实时从新加载。

咱们首先须要安装一下: npm install webpack-dev-server -D

接着咱们须要修改webpack.config.js配置,告诉服务器,在哪里查找文件。

webpack.config.js:

......

module.exports = {
    mode:'development',
    devtool:'cheap-module-eval-source-map',   //映射
    entry:{                     //配置入口文件
        main:'./src/index.js',
        print:'./src/print.js'
    },
    devServer:{
        contentBase:'./dist',      //+++配置运行目录
        open:true,                 //+++自动打开浏览器
        port:8080,                 //+++服务器访问端口
        proxy:{                    //+++配置跨越代理
            'api':'http://loacalhost:3000'
        }
    },
   ......
    plugins:[
        new HtmlWebpackPlugin({
            template: 'src/index.html'   //其会根据该html文件做模板自动导入打包后的js ,然
        }),                             //后将生成的html放到出口文件夹中
        new CleanWebpackPlugin()    //配置删除的文件                              
    ],                             
    output:{                 //打包文件的出口
        filename:'[name].js',          //打包后的文件名
        path:path.resolve(__dirname,'dist')      //打包后文件存放的位置
    }
}

而后咱们只须要在package.json中添加一个script脚本用于启动便可,

 "scripts": {
    "bundle": "webpack",
    "watch": "webpack --watch",
    "server": "webpack-dev-server"    //+++启动wepack-dev-server
  },

运行npm webpack server 就能够看到webpack已经启动了一个服务器。

2.7.3使用webpack-dev-middleware

webpack-dev-middleware是一个容器,它能够吧webpack处理后的文件传递给一个服务器。webpack-dev-server在内部就是使用了它。

这个仅仅了解就能够了,不必本身写一个server,且性能没有webpack-dev-server好。这里主要是配合express server来使用

首先咱们本身安装一下:npm install express webpack-dev-middleware --save-dev

而后咱们须要在webpack.config.js中配置一下

output: {
      filename: '[name].bundle.js',
      path: path.resolve(__dirname, 'dist'),
      publicPath: '/'      //+++
    }

接着咱们须要建立一个server.js

const express = require('express');
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');

const app = express();
const config = require('./webpack.config.js');
const compiler = webpack(config);

// Tell express to use the webpack-dev-middleware and use the webpack.config.js
// configuration file as a base.
app.use(webpackDevMiddleware(compiler, {
  publicPath: config.output.publicPath
}));

// Serve the files on port 3000.
app.listen(3000, function () {
  console.log('Example app listening on port 3000!\n');
});

这时咱们只须要在package.json中添加一个srcipt脚本而后直接运行脚本就能够了

"server": "node server.js",

 

 

2.8模块热替换(HMR)

当咱们启动server时,若是修改某个模块,它就会整个网页从新刷新,以前的操做又得重来。

HMR就是容许运行时更新各类模块,而不用彻底刷新。也就是只更新有变更的模块,其余模板不动。

注:HMR只适合在开发环境下,并不适合在线上环境下配置。

由于HMR是webpack内置的插件,因此无需再下载,在使用以前,咱们先将print.js删除。再引入HMR的相关配置。

webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');  //导入插件
const webpack = require('webpack');     //+++导入webpack

module.exports = {
    mode:'development',
    devtool:'cheap-module-eval-source-map',   //映射
    entry:{                     //配置入口文件
        main:'./src/index.js'
    },
    devServer:{
        contentBase:'./dist',      //配置运行目录
        open:true,                 //自动打开浏览器
        port:8080,                 //服务器访问端口
        proxy:{                    //配置跨越代理
            'api':'http://loacalhost:3000'
        },
        hot:true,              //+++开启热更新
        hotOnly:true            //+++即便html错误,也不让页面更新,           
    },
    ......
    plugins:[
        new HtmlWebpackPlugin({
            template: 'src/index.html'   //其会根据该html文件做模板自动导入打包后的js ,然
        }),                             //后将生成的html放到出口文件夹中
        new CleanWebpackPlugin(),    //配置删除的文件    
        new webpack.NamedModulesPlugin(),        //+++以便更容易查看要修补(patch)的依赖
        new webpack.HotModuleReplacementPlugin()      //+++使用模块热替换插件
    ],                             
    output:{                 //打包文件的出口
        filename:'[name].js',          //打包后的文件名
        path:path.resolve(__dirname,'dist')      //打包后文件存放的位置
    }
}

到这里尚未完  要想实现热替换,还要配置一下index.js

import header from './header'
import content from './content'
import footer from './footer'
import './index.css'    //引入css文件

header();
content();
footer();

//若是模块启用了HMR,就能够用 module.hot.accept(),监听模块的更新。
if (module.hot) {
    module.hot.accept('./header.js', function() {
       header()
    })
  }
  

当咱们单修改header.js时,其余模块并不会影响,只会更新header模块的内容。但咱们会发现修改header会建立一个新的dom。

这是由于咱们每次更新header模块都建立了一个dom 咱们须要先修改一下js代码在更新前先清除以前添加的dom节点。

因此在使用HMR时要根据不一样的代码作相应的设置。

HMR修改样式表

这个就更简单了,其实在上面咱们应该实现了这个功能,无须作任何修改,当咱们修改css样式时,其余模块是不会刷新的。无需设置module.hot.accept。

由于style-loader已经帮咱们在后台使用 module.hot.accept 来修补(patch) <style> 标签。

 

 

2.9 tree shaking

在咱们编写代码时或引入第三方库的时候,不少时候会引入不少冗余的代码,不经意间增大了性能的消耗。

tree shaking是一个术语,一般用于描述移除JavaScript上下问中未引用的代码,其只支持es6模块例如import和export。

实现这个功能很简单,只须要在package.json中配置“sideEffects”属性就能实现。

"sideEffects":["*.css"],   //+++对全部css不使用Tree shaking。

若是将其设置为false则对全部使用tree shaking。若是不想怕误删的文件能够写在数组里。

在生产环境中,其会自动压缩打包,无需设置optimization,若是在开发环境中仍是要配置一下的。

webpack.config.js:

......
module.exports = { mode:'development', devtool:'cheap-module-eval-source-map', //映射 entry:{ //配置入口文件 main:'./src/index.js' }, ...... optimization:{ //+++在开发环境中配置,生产环境不用 usedExports:true }, output:{ //打包文件的出口 filename:'[name].js', //打包后的文件名 path:path.resolve(__dirname,'dist') //打包后文件存放的位置  } }

 

 

2.10生产环境构建

在咱们以前的开发中一直都是以开发环境开发为主,然而生产环境与开发环境有很大的区别,在开发环境中,注重的是怎样使开发更便利,而在生产环境中注重的是若是使代码性能更高,简而精。因此咱们颇有必要将开发环境和生产环境分离出来。

在这里咱们应该抽取出他们的公共部分,再将它们与公共配置分别合并在一块儿,这时,咱们就须要一个工具:webpack-merge

首先,咱们先安装一下这个工具。

npm isntall webpack-merge -D

而后咱们须要建立三个文件:webpack.common.js、webpack.dev.js、webpack.prod.js。咱们将公共部分抽离到webpack.common.js中,删除掉webpack.config.js

 webpack.common.js:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin'); const CleanWebpackPlugin = require('clean-webpack-plugin'); //导入插件 const webpack = require('webpack'); //导入webpack  module.exports = { entry:{ //配置入口文件 main:'./src/index.js' }, module:{ rules:[ { test: /\.js$/, exclude: /node_modules/,//不须要对第三方模块进行转换,耗费性能  use:[ 'babel-loader' ] }, { test:/\.css$/, //配置以css结尾的文件 use:[ //添加翻译官,顺序为由下向上,由右向左 'style-loader', 'css-loader', 'postcss-loader' //配置前缀  ] }, { test:/\.scss$/, use:[ 'style-loader', { loader:'css-loader', options:{ importLoader:2,//若是sass文件还引入其余sass,另外一个会从新从下向上解析 modules:true //开启css模块打包  } }, 'sass-loader', //配置sass翻译官 'postcss-loader' //配置前缀  ] }, { test:/\.(png|jpg|gif|svg)$/, use:[ { loader:'url-loader', options:{ name:'[name].[ext]', outputPath:'images/', limit:8096 //小于4K的图片转化为base64存放到打包后的js中  } } ] }, { test:/\.(woff|woff2|eot|ttf|otf)&/, use:[ 'file-loader' ] } ] }, plugins:[ new HtmlWebpackPlugin({ template: 'src/index.html' //其会根据该html文件做模板自动导入打包后的js ,然 }), //后将生成的html放到出口文件夹中 new CleanWebpackPlugin() //配置删除的文件  ], output:{ //打包文件的出口 filename:'[name].js', //打包后的文件名 path:path.resolve(__dirname,'dist') //打包后文件存放的位置  } }

webpack.dev.js:

const webpack = require('webpack');     //导入webpack
const merge = require('webpack-merge');
const common = require('./webpack.common'); module.exports = merge(common,{ mode:'development', devtool:'cheap-module-eval-source-map', devServer:{ contentBase:'./dist', //配置运行目录 open:true, //自动打开浏览器 port:8080, //服务器访问端口 hot:true //开启热更新  }, plugins:[ new webpack.NamedModulesPlugin(), //以便更容易查看要修补(patch)的依赖 new webpack.HotModuleReplacementPlugin() //使用模块热替换插件  ], optimization:{ //在开发环境中配置,生产环境不用 usedExports:true } })

webpack.prod.js:

const merge = require('webpack-merge');
const common = require('./webpack.common'); module.exports = merge(common,{ mode:'production', devtool:'cheap-module-source-map' })

 接着咱们只需在package.json中配置一下script脚本,运行不一样的脚本进行不一样环境下的打包

package.json:

 "dev":"webpack-dev-server --config ./webpack.dev.js",    "build":"webpack --config ./webpack.prod.js"          
相关文章
相关标签/搜索