webpack实践之路(九):development与production的配置

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/b954960630/article/details/86500924

一、准备工作

在终端输入:

> mkdir webpack_demo
> cd webpack_demo
> mkdir src
> mkdir dist

> npm init -y
> sudo npm install webpack webpack-cli --save-dev

> sudo npm install --save-dev html-webpack-plugin
> sudo npm install clean-webpack-plugin --save-dev
> sudo npm install --save-dev webpack-dev-server
> sudo npm install uglifyjs-webpack-plugin

> sudo npm install --save-dev style-loader css-loader
> sudo npm install --save-dev file-loader
> sudo npm install --save-dev csv-loader xml-loader

目录结构:
在这里插入图片描述
package.json:

{
  "name": "webpack_dome",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack-dev-server --open",
    "build": "webpack" 
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "clean-webpack-plugin": "^1.0.0",
    "css-loader": "^2.1.0",
    "csv-loader": "^3.0.2",
    "file-loader": "^3.0.1",
    "html-webpack-plugin": "^3.2.0",
    "style-loader": "^0.23.1",
    "webpack": "^4.28.4",
    "webpack-cli": "^3.2.1",
    "webpack-dev-server": "^3.1.14",
    "xml-loader": "^1.2.1"
  }
}

webpack.config.js:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');

module.exports={
    entry:{
        app: './src/entry.js'
    },
    devtool: 'inline-source-map',
	devServer: {
		contentBase: './dist'
	},
    plugins: [
		new CleanWebpackPlugin(['dist']),
		new HtmlWebpackPlugin({
			title:'Output Management'
		}),
		new UglifyJSPlugin()
	],
    output:{
		filename: '[name].bundle.js',
        path:path.resolve(__dirname,'dist'),
    },
 }

src/entry.js:

function component() {
	var element = document.createElement('div');
	element.innerHTML = 'Hello webpack';
	return element;
}

document.body.appendChild(component());

运行:

>  npm start

若出现像这样的报错
在这里插入图片描述
Cannot find什么模块,我们就安装什么模块,
这里我们安装uri-js模块,在终端输入:

> sudo npm install --save-dev uri-js

再重新npm start一下,看看有没有问题~


二、重构项目

开发环境(development)和生产环境(production)的构建目标差异很大。

  • 在开发环境中,我们需要具有实时重新加载 或 热模块替换能力的 source map 和 localhost server。
  • 在生产环境中,我们的目标则转向于关注更小的 bundle,更轻量的 source map,以及更优化的资源,以改善加载时间。

由于要遵循逻辑分离,我们通常建议为每个环境编写彼此独立的 webpack 配置:开发环境、生产环境各有一个不同的配置。然后遵循不重复原则:保留一个“通用”配置。
为了将这些配置合并在一起,我们将使用一个名为 webpack-merge 的工具。通过“通用”配置,我们不必在环境特定的配置中重复代码。

接着上面的准备工作,

1、分离代码

重构后的目录结构:
在这里插入图片描述
安装 webpack-merge :

> sudo npm install --save-dev webpack-merge

webpack.common.js:

const path = require('path');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: {
    app: './src/entry.js'
  },
  plugins: [
    new CleanWebpackPlugin(['dist']),
    new HtmlWebpackPlugin({
      title: 'Production'
    })
  ],
  output: {
    filename: '[name].bundle.js',
    path: path.resolve(__dirname, 'dist')
  }
};

webpack.dev.js:

const merge = require('webpack-merge');
const common = require('./webpack.common.js');

module.exports = merge(common, {
  devtool: 'inline-source-map',
  devServer: {
    contentBase: './dist'
  }
});

webpack.prod.js:

const merge = require('webpack-merge');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
const common = require('./webpack.common.js');

module.exports = merge(common, {
  devtool: 'source-map',
  plugins: [
    new UglifyJSPlugin({
       sourceMap: true
    })
  ]
});
  • webpack.common.js 中,我们设置了 entry 和 output 配置,并且在其中引入这两个环境公用的全部插件。
  • webpack.dev.js 中,我们为此环境添加了推荐的 devtool(强大的 source map)和简单的 devServer 配置。
  • webpack.prod.js 中,我们引入了UglifyJSPlugin。然后启用了 source map,因为它有利于调试源码(debug)和运行基准测试。这里我们使用 source-map 选项,而不是在开发环境中用到的 inline-source-map

避免在生产中使用 inline-*** 和 eval-***,因为它们可以增加 bundle 大小,并降低整体性能。


2、NPM Scripts

现在,我们把 scripts 重新指向到新配置。

  • npm start 定义为 开发环境 脚本,并在其中使用 webpack-dev-server
  • npm run build 定义为 生产环境 脚本:

注:npm start后,dist文件夹会消失;npm run build后,dist文件夹又会出现

package.json:

{
  "name": "webpack_dome",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack-dev-server --open --config webpack.dev.js",
    "build": "webpack --config webpack.prod.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "clean-webpack-plugin": "^1.0.0",
    "fast-deep-equal": "^2.0.1",
    "fast-json-stable-stringify": "^2.0.0",
    "html-webpack-plugin": "^3.2.0",
    "json-schema-traverse": "^0.4.1",
    "uri-js": "^4.2.2",
    "webpack": "^4.28.4",
    "webpack-cli": "^3.2.1",
    "webpack-dev-server": "^3.1.14",
    "webpack-merge": "^4.2.1"
  }
}

三、指定环境

许多 library 将通过与 process.env.NODE_ENV 环境变量关联,以决定 library 中应该引用哪些内容。例如,当不处于生产环境中时,某些 library 为了使调试变得容易,可能会添加额外的日志记录(log)和测试(test)。其实,当使用 process.env.NODE_ENV === ‘production’ 时,一些 library 可能针对具体用户的环境进行代码优化,从而删除或添加一些重要代码。我们可以使用 webpack 内置的 DefinePlugin 为所有的依赖定义这个变量:

webpack.prod.js:

const webpack = require('webpack');
const merge = require('webpack-merge');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
const common = require('./webpack.common.js');

module.exports = merge(common, {
	devtool: 'source-map',
	plugins: [
	  	new UglifyJSPlugin({
	    	sourceMap: true
		}),
		new webpack.DefinePlugin({
		   'process.env.NODE_ENV': JSON.stringify('production')
		})
	]
});

技术上讲,NODE_ENV 是一个由 Node.js 暴露给执行脚本的系统环境变量。通常用于决定在开发环境与生产环境(dev-vs-prod)下,服务器工具、构建脚本和客户端 library 的行为。然而,与预期不同的是,无法在构建脚本 webpack.config.js 中,将 process.env.NODE_ENV 设置为 “production”,请查看 #2537。因此,例如 process.env.NODE_ENV === ‘production’ ? ‘[name].[hash].bundle.js’ : ‘[name].bundle.js’ 这样的条件语句,在 webpack 配置文件中,无法按照预期运行。

如果你正在使用像 react 这样的 library,那么在添加此 DefinePlugin 插件后,你应该看到 bundle 大小显著下降。还要注意,任何位于 /src 的本地代码都可以关联到 process.env.NODE_ENV 环境变量,所以以下检查也是有效的:

src/entry.js:

if (process.env.NODE_ENV !== 'production') {
   console.log('Looks like we are in development mode!');
}

function component() {
	var element = document.createElement('div');
	element.innerHTML = 'Hello webpack';
	return element;
}

document.body.appendChild(component());

猜你喜欢

转载自blog.csdn.net/b954960630/article/details/86500924