You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
/* global IS_PRODUCTION:true */if(!IS_PRODUCTION){console.log('如果你看到这个Log,那么这个版本实际上是开发用的版本');}
需要注意的是,如果你在webpack里整合了ESLint,那么,由于ESLint会检测没有定义的变量(ESLint要求使用全局变量时要用window.xxxxx的写法),因此需要一个global注释声明(/* global IS_PRODUCTION:true */)IS_PRODUCTION是一个全局变量(当然在本例中并不是)来规避warning。
前言
开发环境与生产环境分离的原因如下:
如果硬是要在开发环境和生产环境用完全一样的代码,那么必然会付出沉重的代价,这点想必也不用多说了。
下面主要针对两点来介绍如何分离开发环境和生产环境:一是如何以不同的方式进行编译,也即如何分别形成开发环境及生产环境的webpack配置文件;二是在业务代码中如何根据环境的不同而做出不同的处理。
如何分离开发环境和生产环境的webpack配置文件
如果同时把一份完整的开发环境配置文件和一份完整的生产环境配置文件列在一起进行比较,那么会出现以下三种情况:
HotModuleReplacementPlugin
。UglifyJsPlugin
。output.publicPath
,又比如说css-loader
中的minimize
和autoprefixer
参数。更重要的是,实际上开发环境和生产环境的配置文件的绝大部分都是一致的,对于这一致的部分来说,我们坚决要消除冗余,否则后续维护起来不仅麻烦,而且还容易出错。
怎么做呢?
答案很简单:分拆webpack配置文件成N个小module。原先我们是一个完整的配置文件,有好几百行,从头看到尾都头大了,更别说分离不分离的了。下面来看看我分离的结果:
文件目录结构看过了,接下来看一下我是如何组织整理最后的配置文件的:
这样,你就可以很轻松地处理开发/生产环境配置文件中相同与不同的部分了。
如何分别调用开发/生产环境的配置文件呢?
还记得我在《webpack多页应用架构系列(二):webpack配置常用部分有哪些?》里讲过,我们在控制台调用webpack命令来启动打包时,可以添加上
--config
参数来指定webpack配置文件的路径吗?我们可以配合上npm scripts
来使用,在package.json里定义:这样一来,当我们开发的时候就可以使用
npm run dev
或npm run watch
,而到要上线打包的时候就运行npm run build
。业务代码如何判断生产/开发环境
在业务代码里要判断生产/开发环境其实很简单,只需一个变量即可:
这么一来,关键就在于这变量
IS_PRODUCTION
是怎么来的了。在我还没分离开发和生产环境时,我用的办法是,开发时在业务代码所使用的配置文件中把这变量设为
false
,而在最后打包上线时就手动改为true
。这种方法我用过一段时间,非常繁琐,而且经常上线后发现,我嘞个去怎么ajax读的是我本地的mock服务器。怎么做呢?
我参考了许多文章,先粗略讲讲我没有采用的方法:
EnvironmentPlugin
引入process.env,这样就可以在业务代码中靠process.env.NODE_ENV
来判断了。ProvidePlugin
来控制在不同环境里加载不同的配置文件(业务代码用的)。那我用的是什么方法呢?我最后选用的是
DefinePlugin
。举个官方例子,其大概用法是这样的:
DefinePlugin
可能会被误认为其作用是在webpack配置文件中为编译后的代码上下文环境设置全局变量,但其实不然。它真正的机制是:DefinePlugin
的参数是一个object,那么其中会有一些key-value
对。在webpack编译的时候,会把业务代码中没有定义(使用var/const/let来预定义的)而变量名又与key
相同的变量(直接读代码的话的确像是全局变量)替换成value
。例如上面的官方例子,PRODUCTION
就会被替换为true
;VERSION
就会被替换为'5fa3b9'
(注意单引号);BROWSER_SUPPORTS_HTML5
也是会被替换为true
;TWO
会被替换为1+1
(相当于是一个数学表达式);typeof window
就被替换为'object'
了。再举个例子,比如你在代码里是这么写的:
那么在编译生成的代码里就会是这样了:
而如果你用了
UglifyJsPlugin
,则会变成这样:如此一来,只要在俩环境的配置文件里用
DefinePlugin
分别定义好IS_PRODUCTION
的值,我们就可以在业务代码里进行判断了:需要注意的是,如果你在webpack里整合了ESLint,那么,由于ESLint会检测没有定义的变量(ESLint要求使用全局变量时要用
window.xxxxx
的写法),因此需要一个global
注释声明(/* global IS_PRODUCTION:true */
)IS_PRODUCTION是一个全局变量(当然在本例中并不是)来规避warning。示例代码
诸位看本系列文章,搭配我在Github上的脚手架项目食用更佳哦(笑):Array-Huang/webpack-seed(
https://github.com/Array-Huang/webpack-seed
)。The text was updated successfully, but these errors were encountered: