在项目开发的时候,咱们一般会将程序分为开发环境和生产环境,开发环境一般指的是咱们正在开发的这个阶段所须要的一些环境配置,也就是方便咱们开发人员调试开发的一种环境;生产环境一般
是指咱们将程序开发完成后通过测试以后无明显异常准备发布上线的环境,也就是用户能够正常使用的就是生产环境;开发环境(development)和生产环境(production)的构建目标差别很大。css
咱们须要为不一样的开发环境编写彼此独立的webpack配置,还须要一个符合两个环境的通用配置,遵循DRP原则,咱们可使用webpack-merge的工具将这些配置合并在一块儿html
webpack-merge 为webpack设计的合并node
webpack-merge提供了链接数组并合并对象以建立新对象的merge函数。若是遇到函数,它将执行它们,经过算法运行结果,而后将返回的值再次包装在函数中。
尽管此行为具备超出其用途,但在配置webpack时特别有用。每当你须要合并配置对象时,webpack-merge都会派上用场。
还有一个特定于webpack的合并变体,merge.smart该变体可以考虑到webpack的特定状况(及,他能够市价在程序定义变平)mysql
在node中,有全局变量process,表示的是当前的node进程。process.env包含着勇于系统环境的细心。可是process.env中并不存在NODE_ENV这个
东西。NODE_ENV是yoghurt自定义的变量,在webpack中它的用途是判断生产环境或开发环境的依据的webpack
为了查看process对象,咱们能够新建一个process.js 内容为console.log(process)
,而后运行node process.js便可git
process { title: 'C:\\Windows\\System32\\cmd.exe - node webpack.prod.js', version: 'v8.10.0', moduleLoadList: [ 'Binding contextify', 'Binding natives', 'Binding config', 'NativeModule events', 'Binding async_wrap', 'Binding icu', 'NativeModule util', 'NativeModule internal/errors', 'NativeModule internal/encoding', 'NativeModule internal/util', 'Binding util', 'Binding constants', 'NativeModule internal/util/types', 'Binding buffer', 'NativeModule buffer', 'NativeModule internal/buffer', 'Binding uv', 'NativeModule internal/process', 'NativeModule internal/process/warning', 'NativeModule internal/process/next_tick', 'NativeModule internal/async_hooks', 'NativeModule internal/process/promises', 'NativeModule internal/process/stdio', 'Binding performance', 'NativeModule perf_hooks', 'NativeModule internal/linkedlist', 'NativeModule internal/trace_events_async_hooks', 'Binding trace_events', 'NativeModule async_hooks', 'NativeModule internal/inspector_async_hook', 'Binding inspector', 'NativeModule timers', 'Binding timer_wrap', 'NativeModule assert', 'NativeModule module', 'NativeModule internal/module', 'NativeModule internal/url', 'NativeModule internal/querystring', 'NativeModule querystring', 'Binding url', 'NativeModule vm', 'NativeModule fs', 'NativeModule path', 'Binding fs', 'NativeModule stream', 'NativeModule internal/streams/legacy', 'NativeModule _stream_readable', 'NativeModule internal/streams/BufferList', 'NativeModule internal/streams/destroy', 'NativeModule _stream_writable', 'NativeModule _stream_duplex', 'NativeModule _stream_transform', 'NativeModule _stream_passthrough', 'Binding fs_event_wrap', 'NativeModule internal/fs', 'NativeModule internal/loader/Loader', 'NativeModule internal/loader/ModuleWrap', 'Internal Binding module_wrap', 'NativeModule internal/loader/ModuleMap', 'NativeModule internal/loader/ModuleJob', 'NativeModule internal/safe_globals', 'NativeModule internal/loader/ModuleRequest', 'NativeModule url', 'NativeModule internal/loader/search', 'NativeModule console', 'Binding tty_wrap', 'NativeModule tty', 'NativeModule net', 'NativeModule internal/net', 'Binding cares_wrap', 'Binding tcp_wrap', 'Binding pipe_wrap', 'Binding stream_wrap', 'NativeModule dns', 'NativeModule readline', 'NativeModule string_decoder', 'NativeModule internal/readline', 'Binding signal_wrap', 'NativeModule constants' ], versions: { http_parser: '2.7.0', node: '8.10.0', v8: '6.2.414.50', uv: '1.19.1', zlib: '1.2.11', ares: '1.10.1-DEV', modules: '57', nghttp2: '1.25.0', openssl: '1.0.2n', icu: '60.1', unicode: '10.0', cldr: '32.0', tz: '2017c' }, arch: 'x64', platform: 'win32', release: { name: 'node', lts: 'Carbon', sourceUrl: 'https://nodejs.org/download/release/v8.10.0/node-v8.10.0.tar.gz', headersUrl: 'https://nodejs.org/download/release/v8.10.0/node-v8.10.0-headers.tar.gz', libUrl: 'https://nodejs.org/download/release/v8.10.0/win-x64/node.lib' }, argv: [ 'D:\\nodejs\\node.exe', 'C:\\Users\\cvallis\\Desktop\\webpackDemo\\demo\\buildProduction\\webpack.prod.js' ], execArgv: [], env: { ALLUSERSPROFILE: 'C:\\ProgramData', APPDATA: 'C:\\Users\\cvallis\\AppData\\Roaming', 'asl.log': 'Destination=file', CommonProgramFiles: 'C:\\Program Files\\Common Files', 'CommonProgramFiles(x86)': 'C:\\Program Files (x86)\\Common Files', CommonProgramW6432: 'C:\\Program Files\\Common Files', COMPUTERNAME: 'DESKTOP-PH9H8R1', ComSpec: 'C:\\WINDOWS\\system32\\cmd.exe', hdf5_dlls: 'C:\\Windows\\System32', HOMEDRIVE: 'C:', HOMEPATH: '\\Users\\cvallis', 'IntelliJ IDEA': 'D:\\IntelliJIDEA018.3.1\\bin;', LOCALAPPDATA: 'C:\\Users\\cvallis\\AppData\\Local', LOGONSERVER: '\\\\DESKTOP-PH9H8R1', NUMBER_OF_PROCESSORS: '4', OneDrive: 'C:\\Users\\cvallis\\OneDrive', OS: 'Windows_NT', Path: 'D:\\Ruby24-x64\\bin;C:\\WINDOWS\\system32;C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem;C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\;D:\\Python软件\\mysql-5.7.18-winx64\\bin;C;\\Program Files (x86)\\Windows Kits\\8.1\\Windows Performance Toolkit\\;C:\\Windows\\System32;D:\\nodejs\\;D:\\Microsoft VS Code\\bin;D:\\Git\\cmd;C:\\Users\\cvallis\\AppData\\Local\\Programs\\Python\\Python35\\Scripts\\;C:\\Users\\cvallis\\AppData\\Local\\Programs\\Python\\Python35\\;C:\\Users\\cvallis\\AppData\\Local\\Microsoft\\WindowsApps;C:\\Users\\cvallis\\AppData\\Roaming\\npm;D:\\IntelliJIDEA018.3.1\\bin', PATHEXT: '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.RB;.RBW', PROCESSOR_ARCHITECTURE: 'AMD64', PROCESSOR_IDENTIFIER: 'Intel64 Family 6 Model 78 Stepping 3, GenuineIntel', PROCESSOR_LEVEL: '6', PROCESSOR_REVISION: '4e03', ProgramData: 'C:\\ProgramData', ProgramFiles: 'C:\\Program Files', 'ProgramFiles(x86)': 'C:\\Program Files (x86)', ProgramW6432: 'C:\\Program Files', PROMPT: '$P$G', PSModulePath: 'C:\\WINDOWS\\system32\\WindowsPowerShell\\v1.0\\Modules\\', PUBLIC: 'C:\\Users\\Public', SystemDrive: 'C:', SystemRoot: 'C:\\WINDOWS', TEMP: 'C:\\Users\\cvallis\\AppData\\Local\\Temp', TMP: 'C:\\Users\\cvallis\\AppData\\Local\\Temp', USERDOMAIN: 'DESKTOP-PH9H8R1', USERDOMAIN_ROAMINGPROFILE: 'DESKTOP-PH9H8R1', USERNAME: 'cvallis', USERPROFILE: 'C:\\Users\\cvallis', VS140COMNTOOLS: 'C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\Tools\\', windir: 'C:\\WINDOWS' }, pid: 31272, features: { debug: false, uv: true, ipv6: true, tls_npn: true, tls_alpn: true, tls_sni: true, tls_ocsp: true, tls: true }, ppid: 32796, execPath: 'D:\\nodejs\\node.exe', debugPort: 9229, _startProfilerIdleNotifier: [Function: _startProfilerIdleNotifier], _stopProfilerIdleNotifier: [Function: _stopProfilerIdleNotifier], _getActiveRequests: [Function: _getActiveRequests], _getActiveHandles: [Function: _getActiveHandles], reallyExit: [Function: reallyExit], abort: [Function: abort], chdir: [Function], cwd: [Function], umask: [Function: umask], _kill: [Function: _kill], _debugProcess: [Function: _debugProcess], _debugPause: [Function: _debugPause], _debugEnd: [Function: _debugEnd], hrtime: [Function: hrtime], cpuUsage: [Function: cpuUsage], dlopen: [Function: dlopen], uptime: [Function: uptime], memoryUsage: [Function: memoryUsage], binding: [Function: binding], _linkedBinding: [Function: _linkedBinding], _setupDomainUse: [Function: _setupDomainUse], _events: { newListener: [Function], removeListener: [Function], warning: [Function], SIGWINCH: [ [Function], [Function] ] }, _rawDebug: [Function], _eventsCount: 4, domain: null, _maxListeners: undefined, _fatalException: [Function], _exiting: false, assert: [Function], config: { target_defaults: { cflags: [], default_configuration: 'Release', defines: [], include_dirs: [], libraries: [] }, variables: { asan: 0, coverage: false, debug_devtools: 'node', debug_http2: false, debug_nghttp2: false, force_dynamic_crt: 0, host_arch: 'x64', icu_data_file: 'icudt60l.dat', icu_data_in: '..\\..\\deps/icu-small\\source/data/in\\icudt60l.dat', icu_endianness: 'l', icu_gyp_path: 'tools/icu/icu-generic.gyp', icu_locales: 'en,root', icu_path: 'deps/icu-small', icu_small: true, icu_ver_major: '60', node_byteorder: 'little', node_enable_d8: false, node_enable_v8_vtunejit: false, node_install_npm: true, node_module_version: 57, node_no_browser_globals: false, node_prefix: '/usr/local', node_release_urlbase: 'https://nodejs.org/download/release/', node_shared: false, node_shared_cares: false, node_shared_http_parser: false, node_shared_libuv: false, node_shared_nghttp2: false, node_shared_openssl: false, node_shared_zlib: false, node_tag: '', node_use_bundled_v8: true, node_use_dtrace: false, node_use_etw: true, node_use_lttng: false, node_use_openssl: true, node_use_perfctr: true, node_use_v8_platform: true, node_without_node_options: false, openssl_fips: '', openssl_no_asm: 0, shlib_suffix: 'so.57', target_arch: 'x64', v8_enable_gdbjit: 0, v8_enable_i18n_support: 1, v8_enable_inspector: 1, v8_no_strict_aliasing: 1, v8_optimized_debug: 0, v8_promise_internal_field_count: 1, v8_random_seed: 0, v8_trace_maps: 0, v8_use_snapshot: true, want_separate_host_toolset: 0 } }, emitWarning: [Function], nextTick: [Function: nextTick], _tickCallback: [Function: _tickCallback], _tickDomainCallback: [Function: _tickDomainCallback], stdout: [Getter], stderr: [Getter], stdin: [Getter], openStdin: [Function], exit: [Function], kill: [Function], _immediateCallback: [Function: processImmediate], argv0: 'node', mainModule: Module { id: '.', exports: {}, parent: null, filename: 'C:\\Users\\cvallis\\Desktop\\webpackDemo\\demo\\buildProduction\\webpack.prod.js', loaded: false, children: [ [Object], [Object], [Object], [Object], [Object] ], paths: [ 'C:\\Users\\cvallis\\Desktop\\webpackDemo\\demo\\buildProduction\\node_modules', 'C:\\Users\\cvallis\\Desktop\\webpackDemo\\demo\\node_modules', 'C:\\Users\\cvallis\\Desktop\\webpackDemo\\node_modules', 'C:\\Users\\cvallis\\Desktop\\node_modules', 'C:\\Users\\cvallis\\node_modules', 'C:\\Users\\node_modules', 'C:\\node_modules' ] } }
如上咱们能够看到process是node的全局变量,而且process有env这个属性,可是没有NODE_ENV这个属性github
DefinePlugin容许建立一个在编译时能够配置的全局常量。这可能会对开发模式和发布模式的构建容许不一样的行为很是有用。若是在开发构建中,
而再也不发布构建中执行日志记录,则可使用全局常量来决定是否记录日志。这就是DefinePlugin的用处,设置它,就能够忘记开发和发布构建的规则web
每一个传进DefinePlugin的键值都是一个标识符或者多个用.链接起来的标识符算法
提供mode配置选项,告知webpack使用响应的内置优化sql
支持一下字符串值:
development:会将process.env.NODE_ENV的值设为development。启用NamedChunksPlugin和NamedModulesPlugin
production:会将process.env.NODE_ENV的值设置为production。启用FlagDependencyUsagePlugin,FlagIncludedChunksPlugin,
ModuleConcatenationPlugin,NoEmitOnErrorsPlugin,OccurrenceOrderPlugin,SideEfffectsFlagPlugin和UglifyJsPlugin
记住,只设置NODE_ENV,则不会自动设置mode
做用:该插件的主要是为了抽离css样式,防止将样式打包在js中引发页面样式加载错乱的现象
extract-text-webpack-plugin
该插件将css提取到单独的文件中。它为每一个包含css的JS文件建立一个css文件。它支持css和SourceMap的按需加载。
mini-text-extract-plugin
postCSS是由插件来起做用的,使用那个功能,就要安装那个插件,若是只安装了postcss-loader,它并不起做用,还要安装对应的插件autoprefixer等等,安装完成之后,就要进行配置。
对于纯css来讲,咱们最早使用postcss-loader。须要对postcss-loader进行配置,配置的方式有两种,一种是在webpack的配置文件中,一个是单独给postcss写一个配置文件
文件目录以下图所示
import * as Math from "./math.js"; import "./20191031153457.png"; import "./reset.css"; //import "./style.scss"; console.log(Math) function component(){ var element = document.createElement("pre"); element.innerHTML = [ "hello webpack!", "5 cubed is equal to " + Math.cube(5) ].join("\n\n"); return element } document.body.appendChild(component()) console.log(process.env.NODE_ENV)
export function add(a,b){ return a + b; } export function minus(a,b){ return a - b; } export function multiple(a,b){ return a * b; } export function divide(a,b){ return a / b; } export function cube(a){ return a*a*a }
body{ background-color: red; color: #FFFFFF; } /*@import url("./style.scss");*/
body,html{ padding: 0; margin: 0; background-color:black ; color: #FFFFFF; }
const path = require("path"); module.exports = { entry:[path.resolve(__dirname,"src/style.scss"),path.resolve(__dirname,"src/index.js")], output:{ filename:"[name].js", path:path.resolve(__dirname,"dist") }, module:{ rules:[ { test:/\.(png|jpe?g|gif)$/, use:[ { loader:"url-loader", options:{ limit:10000 } } ] } ] } }
const merge = require("webpack-merge"); const common = require("./webpack.common.js"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const webpack = require("webpack"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); module.exports = merge(common,{ mode:"development", module:{ rules:[ { test:/\.(sa|sc|c)ss$/, use:[ "style-loader", "css-loader", "sass-loader" ] } ] }, plugins:[ new HtmlWebpackPlugin({ title:"webpack 构建生产环境" }), new webpack.HotModuleReplacementPlugin() ], devtool:"inline-source-map", devServer:{ hot:true, host:"localhost", port:"8081" } })
const merge = require("webpack-merge"); const common = require("./webpack.common.js"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const {CleanWebpackPlugin} = require("clean-webpack-plugin"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const webpack = require("webpack"); module.exports = merge(common,{ mode:"production", // optimization:{ // splitChunks:{ // chunks:"all" // } // }, module:{ rules:[ { test:/\.(css|scss)$/, use:[ MiniCssExtractPlugin.loader, { loader:"css-loader", options:{ importLoaders:2 } }, "postcss-loader", "sass-loader" ] } ] }, plugins:[ new CleanWebpackPlugin(), new MiniCssExtractPlugin({ filename:"[name].[hash].css", chunkFilename:"[id].[hash].css", allChunks: true, }), new HtmlWebpackPlugin({ title:"webpack 生产环境构建" }) ], devtool:"source-map" })
{ "name": "webpackDevServer", "sideEffects": [ "*.css", ".scss" ], "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "dev": "webpack-dev-server --config demo/webpack-dev-server/webpack-dev-server.js", "server": "node demo/webpack-dev-middleware/server.js", "hmr": "webpack-dev-server --config demo/HMR/webpack.hmr.js", "treeShaking:dev": "webpack-dev-server --config demo/tree-shaking/tree-shaking.js", "treeShaking:build": "webpack --config demo/tree-shaking/tree-shaking.js", "buildProd:dev": "webpack-dev-server --config demo/buildProduction/webpack.dev.js", "buildProd:build": "webpack --config demo/buildProduction/webpack.prod.js" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "@babel/core": "7.6.4", "@babel/plugin-transform-runtime": "^7.6.2", "@babel/preset-env": "^7.6.3", "autoprefixer": "^9.7.1", "babel-loader": "8.0.6", "clean-webpack-plugin": "3.0.0", "css-loader": "^3.2.0", "express": "4.17.1", "file-loader": "^4.2.0", "html-webpack-plugin": "3.2.0", "mini-css-extract-plugin": "^0.8.0", "node-sass": "^4.13.0", "postcss-import": "^12.0.1", "postcss-loader": "^3.0.0", "postcss-url": "^8.0.0", "sass-loader": "8.0.0", "style-loader": "^1.0.0", "url-loader": "^2.2.0", "webpack": "4.41.2", "webpack-cli": "3.3.9", "webpack-dev-middleware": "3.7.2", "webpack-dev-server": "3.8.2", "webpack-merge": "^4.2.2" } }
执行npm run buildProd:dev
结果以下
执行npm run buildProd:build
结果以下
遇到的问题:
import "./style.scss";
打包的时候并无打包对应的css文件,查看了mini-text-extract-plugin的相关资料,该插件将 css提取到单独的文件中。它为每一个包含css的js文件建立一个css文件。它支持css和sourceMap的按需加载,最后解决是在webpack配置文件webpack.common.js 中将其引入在entry中