묻고 답해요
160만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결웹 게임을 만들며 배우는 React
dist 폴더가 생기지 않습니다.
안녕하세요 제로초님! 숫자 야구 강의 듣다가 질문드립니다. 이전 수업에서 나온 내용대로 webpack과 babel 설치 및 설정을 했는데 dist 폴더가 생기지 않습니다. 따로 에러가 뜨진 않았고, 화면도 잘 구동됩니다. 다만, dist 폴더 내에 app.js 파일이 생성되고 그 파일이 html에서 불러와져서 렌더링이 되는 걸로 아는데 dist 폴더가 생기지 않고도 렌더링에 문제가 없는게 맞는건지 여쭙고 싶습니다. 아래는 webpack.config.js 파일입니다. const path = require("path"); const RefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin"); module.exports = { name: "wordrelay-setting", mode: "development", devtool: "eval", resolve: { extensions: [".js", ".jsx"], }, entry: { app: "./client", }, module: { rules: [ { test: /\.jsx?$/, loader: "babel-loader", options: { presets: [ [ "@babel/preset-env", { targets: { browsers: ["> 1% in KR"], }, debug: true, }, ], "@babel/preset-react", ], plugins: ["react-refresh/babel"], }, exclude: path.join(__dirname, "node_modules"), }, ], }, plugins: [new RefreshWebpackPlugin()], output: { path: path.join(__dirname, "dist"), filename: "app.js", publicPath: "/dist", }, devServer: { publicPath: "/dist", hot: true, }, };
-
미해결프론트엔드 개발환경의 이해와 실습 (webpack, babel, eslint..)
file-loader를 이용한 백그라운드 이미지 불러오기 관련 질문 드립니다
안녕하세요 수업 내용대로 file-loader를 이용하여 백그라운드 이미지를 불러오는 실습을 진행하다가 에러가 발생하여 질문 드립니다. 강의에서는 file-loader를 사용하지 않고 .css 파일에서 style-loader와 css-loader만 사용하고 빌드했을 경우에는 에러가 나야하는데 저는 에러가 나지 않고 브라우저에서 열어 봤을 때에 바로 백그라운드 이미지가 나옵니다. 또한 file-loader가 포함된 코드를 webpack.config.js에 추가했을때에는 빌드는 잘 되는데 오히려 브라우저에서 백그라운드 이미지가 나오지 않습니다. style-loader와 css-loader에서 file-loader의 역할을 대신해주도록 업데이트가 된걸까요..? 아래에 패키지 버전과 코드를 남겨드립니다. 패키지 버전 "dependencies": { "css-loader": "^6.2.0", "file-loader": "^6.2.0", "style-loader": "^3.2.1" } } app.js import * as math from './math.js' import './app.css' console.log(math.sum(1,2)); app.css body { background-image: url(bg.png); } webpack.config.js (백그라운드 이미지 뜨는 경우) const path = require('path'); module.exports = { mode: 'development', entry: { main: './src/app.js' }, output: { path: path.resolve('./dist'), filename: '[name].js' }, module: { rules: [ { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] }, ] } } webpack.config.js (백그라운드 이미지 뜨지 않는 경우) const path = require('path'); module.exports = { mode: 'development', entry: { main: './src/app.js' }, output: { path: path.resolve('./dist'), filename: '[name].js' }, module: { rules: [ { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] }, { test: /\.png$/, // .png 확장자로 마치는 모든 파일 loader: "file-loader", options: { publicPath: "./dist/", // prefix를 아웃풋 경로로 지정 name: "[name].[ext]?[hash]", // 파일명 형식 }, }, ] } } 아래와 같은 코드에서 빌드했을 때에 dist/main.js 코드 입니다. /* * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development"). * This devtool is neither made for production nor for readable output files. * It uses "eval()" calls to create a separate source file in the browser devtools. * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/) * or disable the default devtool with "devtool: false". * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/). */ /******/ (() => { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ({ /***/ "./node_modules/css-loader/dist/cjs.js!./src/app.css": /*!***********************************************************!*\ !*** ./node_modules/css-loader/dist/cjs.js!./src/app.css ***! \***********************************************************/ /***/ ((module, __webpack_exports__, __webpack_require__) => { eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../node_modules/css-loader/dist/runtime/api.js */ \"./node_modules/css-loader/dist/runtime/api.js\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../node_modules/css-loader/dist/runtime/getUrl.js */ \"./node_modules/css-loader/dist/runtime/getUrl.js\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_URL_IMPORT_0___ = new URL(/* asset import */ __webpack_require__(/*! bg.png */ \"./src/bg.png\"), __webpack_require__.b);\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0___default()(function(i){return i[1]});\nvar ___CSS_LOADER_URL_REPLACEMENT_0___ = _node_modules_css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_1___default()(___CSS_LOADER_URL_IMPORT_0___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \"body {\\n background-image: url(\" + ___CSS_LOADER_URL_REPLACEMENT_0___ + \");\\n}\", \"\"]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n\n\n//# sourceURL=webpack://npm-sample/./src/app.css?./node_modules/css-loader/dist/cjs.js"); /***/ }), /***/ "./node_modules/css-loader/dist/runtime/api.js": /*!*****************************************************!*\ !*** ./node_modules/css-loader/dist/runtime/api.js ***! \*****************************************************/ /***/ ((module) => { eval("\n\n/*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n*/\n// css base code, injected by the css-loader\n// eslint-disable-next-line func-names\nmodule.exports = function (cssWithMappingToString) {\n var list = []; // return the list of modules as css string\n\n list.toString = function toString() {\n return this.map(function (item) {\n var content = cssWithMappingToString(item);\n\n if (item[2]) {\n return \"@media \".concat(item[2], \" {\").concat(content, \"}\");\n }\n\n return content;\n }).join(\"\");\n }; // import a list of modules into the list\n // eslint-disable-next-line func-names\n\n\n list.i = function (modules, mediaQuery, dedupe) {\n if (typeof modules === \"string\") {\n // eslint-disable-next-line no-param-reassign\n modules = [[null, modules, \"\"]];\n }\n\n var alreadyImportedModules = {};\n\n if (dedupe) {\n for (var i = 0; i < this.length; i++) {\n // eslint-disable-next-line prefer-destructuring\n var id = this[i][0];\n\n if (id != null) {\n alreadyImportedModules[id] = true;\n }\n }\n }\n\n for (var _i = 0; _i < modules.length; _i++) {\n var item = [].concat(modules[_i]);\n\n if (dedupe && alreadyImportedModules[item[0]]) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n if (mediaQuery) {\n if (!item[2]) {\n item[2] = mediaQuery;\n } else {\n item[2] = \"\".concat(mediaQuery, \" and \").concat(item[2]);\n }\n }\n\n list.push(item);\n }\n };\n\n return list;\n};\n\n//# sourceURL=webpack://npm-sample/./node_modules/css-loader/dist/runtime/api.js?"); /***/ }), /***/ "./node_modules/css-loader/dist/runtime/getUrl.js": /*!********************************************************!*\ !*** ./node_modules/css-loader/dist/runtime/getUrl.js ***! \********************************************************/ /***/ ((module) => { eval("\n\nmodule.exports = function (url, options) {\n if (!options) {\n // eslint-disable-next-line no-param-reassign\n options = {};\n }\n\n if (!url) {\n return url;\n } // eslint-disable-next-line no-underscore-dangle, no-param-reassign\n\n\n url = String(url.__esModule ? url.default : url); // If url is already wrapped in quotes, remove them\n\n if (/^['\"].*['\"]$/.test(url)) {\n // eslint-disable-next-line no-param-reassign\n url = url.slice(1, -1);\n }\n\n if (options.hash) {\n // eslint-disable-next-line no-param-reassign\n url += options.hash;\n } // Should url be wrapped?\n // See https://drafts.csswg.org/css-values-3/#urls\n\n\n if (/[\"'() \\t\\n]|(%20)/.test(url) || options.needQuotes) {\n return \"\\\"\".concat(url.replace(/\"/g, '\\\\\"').replace(/\\n/g, \"\\\\n\"), \"\\\"\");\n }\n\n return url;\n};\n\n//# sourceURL=webpack://npm-sample/./node_modules/css-loader/dist/runtime/getUrl.js?"); /***/ }), /***/ "./src/bg.png": /*!********************!*\ !*** ./src/bg.png ***! \********************/ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { eval("module.exports = __webpack_require__.p + \"3d9f2814733b516c33db.png\";\n\n//# sourceURL=webpack://npm-sample/./src/bg.png?"); /***/ }), /***/ "./src/app.css": /*!*********************!*\ !*** ./src/app.css ***! \*********************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js */ \"./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\");\n/* harmony import */ var _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/styleDomAPI.js */ \"./node_modules/style-loader/dist/runtime/styleDomAPI.js\");\n/* harmony import */ var _node_modules_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _node_modules_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/insertBySelector.js */ \"./node_modules/style-loader/dist/runtime/insertBySelector.js\");\n/* harmony import */ var _node_modules_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var _node_modules_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js */ \"./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\");\n/* harmony import */ var _node_modules_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var _node_modules_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/insertStyleElement.js */ \"./node_modules/style-loader/dist/runtime/insertStyleElement.js\");\n/* harmony import */ var _node_modules_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var _node_modules_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/styleTagTransform.js */ \"./node_modules/style-loader/dist/runtime/styleTagTransform.js\");\n/* harmony import */ var _node_modules_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5__);\n/* harmony import */ var _node_modules_css_loader_dist_cjs_js_app_css__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! !!../node_modules/css-loader/dist/cjs.js!./app.css */ \"./node_modules/css-loader/dist/cjs.js!./src/app.css\");\n\n \n \n \n \n \n \n \n \n \n\nvar options = {};\n\noptions.styleTagTransform = (_node_modules_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5___default());\noptions.setAttributes = (_node_modules_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3___default());\n\n options.insert = _node_modules_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2___default().bind(null, \"head\");\n \noptions.domAPI = (_node_modules_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1___default());\noptions.insertStyleElement = (_node_modules_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4___default());\n\nvar update = _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0___default()(_node_modules_css_loader_dist_cjs_js_app_css__WEBPACK_IMPORTED_MODULE_6__.default, options);\n\n\n\n\n /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (_node_modules_css_loader_dist_cjs_js_app_css__WEBPACK_IMPORTED_MODULE_6__.default && _node_modules_css_loader_dist_cjs_js_app_css__WEBPACK_IMPORTED_MODULE_6__.default.locals ? _node_modules_css_loader_dist_cjs_js_app_css__WEBPACK_IMPORTED_MODULE_6__.default.locals : undefined);\n\n\n//# sourceURL=webpack://npm-sample/./src/app.css?"); /***/ }), /***/ "./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js": /*!****************************************************************************!*\ !*** ./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js ***! \****************************************************************************/ /***/ ((module) => { eval("\n\nvar stylesInDom = [];\n\nfunction getIndexByIdentifier(identifier) {\n var result = -1;\n\n for (var i = 0; i < stylesInDom.length; i++) {\n if (stylesInDom[i].identifier === identifier) {\n result = i;\n break;\n }\n }\n\n return result;\n}\n\nfunction modulesToDom(list, options) {\n var idCountMap = {};\n var identifiers = [];\n\n for (var i = 0; i < list.length; i++) {\n var item = list[i];\n var id = options.base ? item[0] + options.base : item[0];\n var count = idCountMap[id] || 0;\n var identifier = \"\".concat(id, \" \").concat(count);\n idCountMap[id] = count + 1;\n var index = getIndexByIdentifier(identifier);\n var obj = {\n css: item[1],\n media: item[2],\n sourceMap: item[3]\n };\n\n if (index !== -1) {\n stylesInDom[index].references++;\n stylesInDom[index].updater(obj);\n } else {\n stylesInDom.push({\n identifier: identifier,\n updater: addStyle(obj, options),\n references: 1\n });\n }\n\n identifiers.push(identifier);\n }\n\n return identifiers;\n}\n\nfunction addStyle(obj, options) {\n var api = options.domAPI(options);\n api.update(obj);\n return function updateStyle(newObj) {\n if (newObj) {\n if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap) {\n return;\n }\n\n api.update(obj = newObj);\n } else {\n api.remove();\n }\n };\n}\n\nmodule.exports = function (list, options) {\n options = options || {};\n list = list || [];\n var lastIdentifiers = modulesToDom(list, options);\n return function update(newList) {\n newList = newList || [];\n\n for (var i = 0; i < lastIdentifiers.length; i++) {\n var identifier = lastIdentifiers[i];\n var index = getIndexByIdentifier(identifier);\n stylesInDom[index].references--;\n }\n\n var newLastIdentifiers = modulesToDom(newList, options);\n\n for (var _i = 0; _i < lastIdentifiers.length; _i++) {\n var _identifier = lastIdentifiers[_i];\n\n var _index = getIndexByIdentifier(_identifier);\n\n if (stylesInDom[_index].references === 0) {\n stylesInDom[_index].updater();\n\n stylesInDom.splice(_index, 1);\n }\n }\n\n lastIdentifiers = newLastIdentifiers;\n };\n};\n\n//# sourceURL=webpack://npm-sample/./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js?"); /***/ }), /***/ "./node_modules/style-loader/dist/runtime/insertBySelector.js": /*!********************************************************************!*\ !*** ./node_modules/style-loader/dist/runtime/insertBySelector.js ***! \********************************************************************/ /***/ ((module) => { eval("\n\nvar memo = {};\n/* istanbul ignore next */\n\nfunction getTarget(target) {\n if (typeof memo[target] === \"undefined\") {\n var styleTarget = document.querySelector(target); // Special case to return head of iframe instead of iframe itself\n\n if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {\n try {\n // This will throw an exception if access to iframe is blocked\n // due to cross-origin restrictions\n styleTarget = styleTarget.contentDocument.head;\n } catch (e) {\n // istanbul ignore next\n styleTarget = null;\n }\n }\n\n memo[target] = styleTarget;\n }\n\n return memo[target];\n}\n/* istanbul ignore next */\n\n\nfunction insertBySelector(insert, style) {\n var target = getTarget(insert);\n\n if (!target) {\n throw new Error(\"Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.\");\n }\n\n target.appendChild(style);\n}\n\nmodule.exports = insertBySelector;\n\n//# sourceURL=webpack://npm-sample/./node_modules/style-loader/dist/runtime/insertBySelector.js?"); /***/ }), /***/ "./node_modules/style-loader/dist/runtime/insertStyleElement.js": /*!**********************************************************************!*\ !*** ./node_modules/style-loader/dist/runtime/insertStyleElement.js ***! \**********************************************************************/ /***/ ((module) => { eval("\n\n/* istanbul ignore next */\nfunction insertStyleElement(options) {\n var style = document.createElement(\"style\");\n options.setAttributes(style, options.attributes);\n options.insert(style);\n return style;\n}\n\nmodule.exports = insertStyleElement;\n\n//# sourceURL=webpack://npm-sample/./node_modules/style-loader/dist/runtime/insertStyleElement.js?"); /***/ }), /***/ "./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js": /*!**********************************************************************************!*\ !*** ./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js ***! \**********************************************************************************/ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { eval("\n\n/* istanbul ignore next */\nfunction setAttributesWithoutAttributes(style) {\n var nonce = true ? __webpack_require__.nc : 0;\n\n if (nonce) {\n style.setAttribute(\"nonce\", nonce);\n }\n}\n\nmodule.exports = setAttributesWithoutAttributes;\n\n//# sourceURL=webpack://npm-sample/./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js?"); /***/ }), /***/ "./node_modules/style-loader/dist/runtime/styleDomAPI.js": /*!***************************************************************!*\ !*** ./node_modules/style-loader/dist/runtime/styleDomAPI.js ***! \***************************************************************/ /***/ ((module) => { eval("\n\n/* istanbul ignore next */\nfunction apply(style, options, obj) {\n var css = obj.css;\n var media = obj.media;\n var sourceMap = obj.sourceMap;\n\n if (media) {\n style.setAttribute(\"media\", media);\n } else {\n style.removeAttribute(\"media\");\n }\n\n if (sourceMap && typeof btoa !== \"undefined\") {\n css += \"\\n/*# sourceMappingURL=data:application/json;base64,\".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), \" */\");\n } // For old IE\n\n /* istanbul ignore if */\n\n\n options.styleTagTransform(css, style);\n}\n\nfunction removeStyleElement(style) {\n // istanbul ignore if\n if (style.parentNode === null) {\n return false;\n }\n\n style.parentNode.removeChild(style);\n}\n/* istanbul ignore next */\n\n\nfunction domAPI(options) {\n var style = options.insertStyleElement(options);\n return {\n update: function update(obj) {\n apply(style, options, obj);\n },\n remove: function remove() {\n removeStyleElement(style);\n }\n };\n}\n\nmodule.exports = domAPI;\n\n//# sourceURL=webpack://npm-sample/./node_modules/style-loader/dist/runtime/styleDomAPI.js?"); /***/ }), /***/ "./node_modules/style-loader/dist/runtime/styleTagTransform.js": /*!*********************************************************************!*\ !*** ./node_modules/style-loader/dist/runtime/styleTagTransform.js ***! \*********************************************************************/ /***/ ((module) => { eval("\n\n/* istanbul ignore next */\nfunction styleTagTransform(css, style) {\n if (style.styleSheet) {\n style.styleSheet.cssText = css;\n } else {\n while (style.firstChild) {\n style.removeChild(style.firstChild);\n }\n\n style.appendChild(document.createTextNode(css));\n }\n}\n\nmodule.exports = styleTagTransform;\n\n//# sourceURL=webpack://npm-sample/./node_modules/style-loader/dist/runtime/styleTagTransform.js?"); /***/ }), /***/ "./src/app.js": /*!********************!*\ !*** ./src/app.js ***! \********************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _math_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./math.js */ \"./src/math.js\");\n/* harmony import */ var _app_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./app.css */ \"./src/app.css\");\n\n\n\nconsole.log(_math_js__WEBPACK_IMPORTED_MODULE_0__.sum(1,2));\n\n//# sourceURL=webpack://npm-sample/./src/app.js?"); /***/ }), /***/ "./src/math.js": /*!*********************!*\ !*** ./src/math.js ***! \*********************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"sum\": () => (/* binding */ sum)\n/* harmony export */ });\nfunction sum(a,b) {\n return a+b;\n}\n\n//# sourceURL=webpack://npm-sample/./src/math.js?"); /***/ }) /******/ }); /************************************************************************/ /******/ // The module cache /******/ var __webpack_module_cache__ = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ var cachedModule = __webpack_module_cache__[moduleId]; /******/ if (cachedModule !== undefined) { /******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { /******/ id: moduleId, /******/ // no module.loaded needed /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = __webpack_modules__; /******/ /************************************************************************/ /******/ /* webpack/runtime/compat get default export */ /******/ (() => { /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = (module) => { /******/ var getter = module && module.__esModule ? /******/ () => (module['default']) : /******/ () => (module); /******/ __webpack_require__.d(getter, { a: getter }); /******/ return getter; /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/define property getters */ /******/ (() => { /******/ // define getter functions for harmony exports /******/ __webpack_require__.d = (exports, definition) => { /******/ for(var key in definition) { /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); /******/ } /******/ } /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/global */ /******/ (() => { /******/ __webpack_require__.g = (function() { /******/ if (typeof globalThis === 'object') return globalThis; /******/ try { /******/ return this || new Function('return this')(); /******/ } catch (e) { /******/ if (typeof window === 'object') return window; /******/ } /******/ })(); /******/ })(); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/make namespace object */ /******/ (() => { /******/ // define __esModule on exports /******/ __webpack_require__.r = (exports) => { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/publicPath */ /******/ (() => { /******/ var scriptUrl; /******/ if (__webpack_require__.g.importScripts) scriptUrl = __webpack_require__.g.location + ""; /******/ var document = __webpack_require__.g.document; /******/ if (!scriptUrl && document) { /******/ if (document.currentScript) /******/ scriptUrl = document.currentScript.src /******/ if (!scriptUrl) { /******/ var scripts = document.getElementsByTagName("script"); /******/ if(scripts.length) scriptUrl = scripts[scripts.length - 1].src /******/ } /******/ } /******/ // When supporting browsers where an automatic publicPath is not supported you must specify an output.publicPath manually via configuration /******/ // or pass an empty string ("") and set the __webpack_public_path__ variable from your code to use your own logic. /******/ if (!scriptUrl) throw new Error("Automatic publicPath is not supported in this browser"); /******/ scriptUrl = scriptUrl.replace(/#.*$/, "").replace(/\?.*$/, "").replace(/\/[^\/]+$/, "/"); /******/ __webpack_require__.p = scriptUrl; /******/ })(); /******/ /******/ /* webpack/runtime/jsonp chunk loading */ /******/ (() => { /******/ __webpack_require__.b = document.baseURI || self.location.href; /******/ /******/ // object to store loaded and loading chunks /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched /******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded /******/ var installedChunks = { /******/ "main": 0 /******/ }; /******/ /******/ // no chunk on demand loading /******/ /******/ // no prefetching /******/ /******/ // no preloaded /******/ /******/ // no HMR /******/ /******/ // no HMR manifest /******/ /******/ // no on chunks loaded /******/ /******/ // no jsonp function /******/ })(); /******/ /************************************************************************/ /******/ /******/ // startup /******/ // Load entry module and return exports /******/ // This entry module can't be inlined because the eval devtool is used. /******/ var __webpack_exports__ = __webpack_require__("./src/app.js"); /******/ /******/ })() ;
-
해결됨Slack 클론 코딩[실시간 채팅 with React]
InviteChannelModal 에 관해서 여쭤볼게 있습니다!
먼저 좋은 강의 감사드립니다 제로초님! 도움 많이 되고 있습니다. 여기서 위 그림과 같이 console을 찍어서 useParams를 통해 받아온 channel이 잘 들어오는지 확인을 하려했는데.. workspace는 잘 들어오는 반면 channel은 undefined로 나옵니다. 그래서 InviteChannelModal에서 SWR로 요청을 보낼 때 콘솔에 에러가 발생하구요!제 생각에는 아래 그림과 같이 '일반'으로 라고 콘솔에 떠야할 것 같은데.. 이유를 잘 모르겠습니다.
-
해결됨Slack 클론 코딩[실시간 채팅 with React]
SPA에서 e.preventDefault()를 사용해야하는 이유가 뭔가요?
https://developer.mozilla.org/ko/docs/Web/API/Event/preventDefault - 위의 링크에서 e.preventDefault() 함수가, 이벤트가 취소 가능한 경우 이벤트의 전파를 막지 않고 이벤트를 취소한다고 되어 있는데, 설명중에서 SPA에서 e.preventDefault() 사용해야한다고 하셨는데 이유가 궁금합니다.
-
미해결Slack 클론 코딩[실시간 채팅 with React]
socket.io-client typescript 모듈 에러 관련
현재 시점으로 npm i @types/socket.io-client하면 3.0.0 버전으로 설치가되어 2버전과 맞지 않아 에러가 나옵니다. 저 같은 경우는 제로초님의 깃헙에 올라와있는 json을 보고 1.4.35 버전으로 명시하여 설치하여 문제를 해결하였습니다. 혹시 문제 있으신 분 확인해보세요. npm i -D @types/socket.io-client@1.4.35
-
미해결Slack 클론 코딩[실시간 채팅 with React]
dedupingInterval에 관련해서 질문드립니다!
제가 이 강의를 듣고 이해한게 맞는지 궁금해서 질문올립니다! dedupingInterval을 사용하지 않으면 swr이 재요청 하는 기준이 다른 텝을 갔다가 오는 경우 재요청을 보내게 되고 dedupingInterval 옵션을 추가하게 되면 그 시간안에는 탭을 갔다와도 재요청을 보내지 않고 캐시해서 그대로 데이터를 사용하다가 그 시간이 끝나면 다시 재요청을 보내는 것이 맞는지 궁금합니다!
-
미해결Slack 클론 코딩[실시간 채팅 with React]
Login에서 mutate 대신 revalidate를 써야 하네요.
저번에 mutate를 이용해서 서버에서 가져오는 데이터를 바로 data에 집어 넣는 식으로 했었는데, 그걸 유지했더니 리다이렉트 할때 에러가 나는 군요. .then((response) => { mutate(response.data) }) 리다이렉트를 할 때 워크스페이스 페이지가 열림과 동시에 user를 가져와야 에러가 안 생기는데, mutate를 쓰면 워크스페이스 페이지가 열릴 때 서버에 요청을 안보내네요... 그래서 실습 코드 뒤져보다가 revalidate를 쓴 걸 보고 revalidate를 쓰도록 코드를 수정했더니 workspace 들어가자마자 user 요청을 보내네요. 아직 알쏭달쏭 합니다. swr은 로컬 스토리지를 쓸때 디버깅을 하기가 어려운 것 같아요.
-
미해결Slack 클론 코딩[실시간 채팅 with React]
안녕하세요. 프론트엔드 세팅하기 챕터 질문입니다.
안녕하세요 zerocho님. 이번 강의에서 [프론트엔드 세팅하기] 챕터 관련해서 질문드립니다. 강의 후반부에서 babel이 image, css 파일 등을 js파일로 변환한다고 하셨는데 그게 아니라 webpack의 loader(style-loader, file-loader) 가 js파일로 번들링 해주는거 아닌가요? 혹시 제가 모르는 부분이 있나해서 이렇게 문의드립니다. 혹시 참고할만한 문서가 있다면 같이 주시면 도움 될 것 같습니다:) 감사합니다.
-
미해결Slack 클론 코딩[실시간 채팅 with React]
커스텀 훅 useInput에서 Dispatch<SetStateAction<T>>에 관한 설명을 어디서 찾아볼수 있을까요?
커스텀 훅 useInput에서 Dispatch<SetStateAction<T>>에 관한 설명을 어디서 찾아볼수 있을까요?
-
해결됨프론트엔드 개발환경의 이해와 실습 (webpack, babel, eslint..)
husky도 버전이 변경되었나 봐요..
버전 5가 되면서 package.json 파일에서 입력하는게 아니고 npx husky add .husky/pre-commit "npx eslint app.js --fix" 이런식으로 생성해서 하는 것으로 바뀐것 같네요. (여기서는 npx를 안넣어주면 실행이 안되네요...) 아니면 package.json에서 하는 방법이 있는데 제가 못찾은 것 일수도 있구용... ps. npm install husky@4 로 설치하면 기존의 방식대로 할 수 있네요.. 문제는 lint-staged를 어떻게 쓰는지 모르겠네요...
-
해결됨프론트엔드 개발환경의 이해와 실습 (webpack, babel, eslint..)
npm install -D
npm install -D @babel/preset-env 라 적혀 있는데 실제론 npm install @babel/preset-env 라고 하기도 하고.... -D가 dev에 추가한다. 라고는 알고 있는데, 실제로 바벨 프리셋들은 dev에 했을 때와 아닐때 차이가 없나요? 아니면 차이점으로 어떤 것들이 있나요?
-
미해결프론트엔드 개발환경의 이해와 실습 (webpack, babel, eslint..)
프로젝트 생성
초반에 프로젝트 생성 파트를 보고있습니다. node.js를설치후 강좌에서 본것처럼 npm 을 타이핑 하였지만 Uncaught ReferenceError: npm is not defined 이라는 메세지만 나타납니다. 그리고 프로젝트 생성하실때 강좌에서는 mkdir sample 그리고 cd sample후에 sample npm init를 치시면 프로젝트 생성 이 되는데 저는 mkdir sample을 타이핑하면 Uncaught SyntaxError: Unexpected identifier이 나타납니다. 이유를 알고싶습니다. 강좌보고 5분만에 막히네요 ㅜㅜ;;
-
미해결프론트엔드 개발환경의 이해와 실습 (webpack, babel, eslint..)
콘솔찍은건 잘 뜨는데 콘솔이 알랏으로 변경되지 않습니다
module.exports = function myWebpackLoader (content){ console.log("실행"); return content.replace('console.log(','alert('); } 으로 빌드하면 실행 콘솔 찍은것 2번 나오고 [webpack-cli] Compilation finished뜹니다 npx lite-server로 서버 구동하여 확인하면 알랏이 안뜨고 콘솔로 3이 뜹니다 일부러 module.exports = function myWebpackLoader (content){ console.log("실행"); return content.replace('console','alert('); } 이런식으로 콘솔글자를 바꿔서 빌드하면 You may need an additional loader to handle the result of these loaders. | import * as math from './math.js'; > alert(.log(math.sum(1,2)); 라는 에러가 뜹니다 replace가 동작을 하는것 같긴 한데 왜 콘솔을 알랏으로 바꾸지 못하는것일까요?
-
미해결프론트엔드 개발환경의 이해와 실습 (webpack, babel, eslint..)
compiler.plugin 이 undefined라고 뜹니다.
안녕하세요 TypeError: compiler.plugin is not a function 위와 같은 에러가 떠서 compiler를 찍어봤더니 plugin이 존재하지 않아서 undefined라고 뜹니다. compiler.hooks.emit.tapAsync( 'emit', (compilation, callback) => { const source = compilation.assets['main.js'].source(); console.log(source); callback(); }) } 이 방식을 사용하면 똑같이 나오는데 버전이 바뀐 것인가요?
-
해결됨프론트엔드 개발환경의 이해와 실습 (webpack, babel, eslint..)
target 관련 질문
안녕하세요. 수업 잘 듣고 있습니다. 질문이 있어 글을 올립니다. 만약 targets : {ie: 11}을 지원하게 된다면 ie 11보다 최신 브라우저인 사파리, 오페라, 엣지,크롬들은 전부 지원된다고 보면 되나요? 그리고 ie11도 버전이 있는것으로 알고 있는데 ie11의 모든버전을 제공하는 것이겠죠?
-
미해결프론트엔드 개발환경의 이해와 실습 (webpack, babel, eslint..)
수업을 듣고 궁금한 점이 있습니다!
우선 좋은 강의 감사합니다. 😄 개발 환경을 구현하고 나서 그 후에 이 환경에서 어떤 방식으로 개발을 진행하는지 궁금합니다. 기본적인 프로젝트 구조나, routing 등 프론트엔드 실무에서 사용하는 여러가지들을 해당 환경에 적용하는 방법을 알 수 있을까요? 항상 구조가 짜여져 있는 환경에서 개발을 하다가 직접 환경을 구성하는 연습을 해보니 감이 잘 잡히지 않네요... ㅠ