在項目開發的時候,咱們一般會將程序分爲開發環境和生產環境,開發環境一般指的是咱們正在開發的這個階段所須要的一些環境配置,也就是方便咱們開發人員調試開發的一種環境;生產環境一般
是指咱們將程序開發完成後通過測試以後無明顯異常準備發佈上線的環境,也就是用戶能夠正常使用的就是生產環境;開發環境(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中