关于vue-cli4:webpack配置publicPath无效问题

背景我的项目应用vue-cli-service@4打包一个bundle.js;心愿bundle援用的文件应用cdn,然而发现publicPath设置有效: 咱们打印了最终生成的webpack config // 打印 configapi.configureWebpack(config => { console.log('hyhy', config);});// 打印后果{ ... output: { path: '/ks-puzzle/custom-widgets/customization-table/dist', filename: '[name].js', publicPath: 'https://hyhyhy.com', libraryTarget: 'umd' }, ...}能够看到咱们设置的publicPath是失效的;然而生成的打包产物中publicPath未失效,如下: .../******/ // Object.prototype.hasOwnProperty.call/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };/******//******/ // __webpack_public_path__/******/ __webpack_require__.p = "";/******//******/ // on error function for async loading/******/ __webpack_require__.oe = function(err) { console.error(err); throw err; };...这里的__webpack_require__.p就是publicPath,值是空字符串,设置有效。 遇到问题后首先百度谷歌了一下publicPath not work等相干关键字,一段时间后未找到答案,开始进入源码找起因。 切入点:__webpack_require__.p咱们来到webpack中设置__webpack_require__.p的中央; 能够看到这里设置得publicPath为空字符串。以这里为终点开始追究 webpack入口始终追溯到了webpack的终点 能够看到webpack接管到的publicPath就是空值,那么问题可能出在上一层也就是vue-cli-service这一层 vue-cli-service对publicPath的解决在包@vue/cli-service中搜寻publicPath,找到了上面这段代码 能够看到当应用vue-cli-service进行lib形式打包时,publicPath会恒置为空。问题定位到了 解决方案获取到了进一步的信息后,从新进入谷歌搜寻vue-cli-service target lib publicPath not work; ...

June 28, 2023 · 1 min · jiezi

关于vue-cli4:源码vuecli459三

前言上文介绍了vue create的大抵过程,上面要介绍vue add和vue invoke的执行过程,其实vue add实质上还是执行vue invoke,只不过多了插件装置的相干逻辑而已 vue create如果你想在一个曾经被创立好的我的项目中装置一个插件,能够应用 vue add 命令:program .command('add <plugin> [pluginOptions]') .description('install a plugin and invoke its generator in an already created project') .option('--registry <url>', 'Use specified npm registry when installing dependencies (only for npm)') .allowUnknownOption() .action((plugin) => { require('../lib/add')(plugin, minimist(process.argv.slice(3))) })plugin: 装置的插件名称minimist(process.argv.slice(3)): pluginOptions对象add.js文件门路: `` module.exports = (...args) => { return add(...args).catch(err => { error(err) if (!process.env.VUE_CLI_TEST) { process.exit(1) } })}add func/** * @param pluginToAdd 待增加插件名称 * @param pluginToAdd 额定参数 * @param context 命令行执行门路 */async function add (pluginToAdd, options = {}, context = process.cwd()) { if (!(await confirmIfGitDirty(context))) { return } // for `vue add` command in 3.x projects const servicePkg = loadModule('@vue/cli-service/package.json', context) if (servicePkg && semver.satisfies(servicePkg.version, '3.x')) { // special internal "plugins" if (/^(@vue\/)?router$/.test(pluginToAdd)) { return addRouter(context) } if (/^(@vue\/)?vuex$/.test(pluginToAdd)) { return addVuex(context) } } const pluginRe = /^(@?[^@]+)(?:@(.+))?$/ const [ // eslint-disable-next-line _skip, pluginName, pluginVersion ] = pluginToAdd.match(pluginRe) const packageName = resolvePluginId(pluginName) log() log(` Installing ${chalk.cyan(packageName)}...`) log() const pm = new PackageManager({ context }) if (pluginVersion) { await pm.add(`${packageName}@${pluginVersion}`) } else if (isOfficialPlugin(packageName)) { const { latestMinor } = await getVersions() await pm.add(`${packageName}@~${latestMinor}`) } else { await pm.add(packageName, { tilde: true }) } log(`${chalk.green('✔')} Successfully installed plugin: ${chalk.cyan(packageName)}`) log() const generatorPath = resolveModule(`${packageName}/generator`, context) if (generatorPath) { invoke(pluginName, options, context) } else { log(`Plugin ${packageName} does not have a generator to invoke`) }}首先执行confirmIfGitDirty办法,它会判断是否为执行命令行门路是否为git仓库,不是则继续执行上面流程,如果是则判断是git仓库,则判断仓库状态是否已提交,如果没有提交则提醒用户。接下来则是判断@vue/cli-service是否为3.x版本,如果是,则再判断是否为vue add router或vue add vuex去执行装置插件步骤,不过4.0版本开始,router和vuex这个2个cli插件被拆分成@vue/cli-plugin-router与@vue/cli-plugin-vuex,不作为外部的非凡插件。理解即可。而后就是通过resolvePluginId获取残缺的插件名称。通过上文的提到的PackageManager实例pm来下载插件。接着通过resolveModule办法动态创建require语句来引入插件的generator文件夹。若存在该门路,则间接调用invoke办法执行插件的generator逻辑。而invoke正是vue invoke命令调用的执行函数。 ...

February 28, 2022 · 3 min · jiezi

关于vue-cli4:源码vuecli459二

前言上文简略介绍了vue -V的执行过程,本文在此基础上,持续剖析vue create的执行过程,理解vue create <app-name>经验了哪些过程 ?注释文件门路:/packages/@vue/cli/bin/vue.js program .command('create <app-name>') .description('create a new project powered by vue-cli-service') .option('-p, --preset <presetName>', 'Skip prompts and use saved or remote preset') // 省略option相干代码 ... .action((name, cmd) => { const options = cleanArgs(cmd) if (minimist(process.argv.slice(3))._.length > 1) { console.log(chalk.yellow('\n Info: You provided more than one argument. The first one will be used as the app\'s name, the rest are ignored.')) } // --git makes commander to default git to true if (process.argv.includes('-g') || process.argv.includes('--git')) { options.forceGit = true } require('../lib/create')(name, options) })commander解析到create <app-name>命令,会主动执行action办法中的回调函数。首先是调用cleanArgs办法,它的作用是将传递的Command对象cnd,提取理论的选项到一个新对象中作为options,次要是为了可读性,5.0版本曾经将这个办法删除。间接传递Command对象作为options变量,理解即可。而后就是校验命令输出的非options参数是否超过1个,若是则揭示用户,将应用第一个非option参数作为项目名称。其次是判断是否有-g选项并从新赋值forceGit防止歧义。最重要就是执行/lib/create函数。 ...

February 27, 2022 · 9 min · jiezi

关于vue-cli4:源码vuecli459一

vue -V产生过程 入口文件文件门路:/packages/@vue/cli/bin/vue.js checkNodeVersion运行vue.js,第一步就是校验Node版本是否合乎package.json中的engines.node的node版本。 const requiredVersion = require('../package.json').engines.nodefunction checkNodeVersion (wanted, id) { if (!semver.satisfies(process.version, wanted, { includePrerelease: true })) { console.log(chalk.red( 'You are using Node ' + process.version + ', but this version of ' + id + ' requires Node ' + wanted + '.\nPlease upgrade your Node version.' )) process.exit(1) }}checkNodeVersion(requiredVersion, '@vue/cli')其中npm包semver的satisfies办法校验版本是否合乎,若不合乎则退出运行过程。 随后判断Node版本若不是LTS版本,则正告用户降级。 const EOL_NODE_MAJORS = ['8.x', '9.x', '11.x', '13.x']for (const major of EOL_NODE_MAJORS) { if (semver.satisfies(process.version, major)) { console.log(chalk.red( `You are using Node ${process.version}.\n` + `Node.js ${major} has already reached end-of-life and will not be supported in future major releases.\n` + `It's strongly recommended to use an active LTS version instead.` )) }}commander 执行命令行输出commander是一个笨重的nodejs模块,提供了用户命令行输出和参数解析弱小性能。具体能够见上面的参考文章 ...

February 26, 2022 · 1 min · jiezi

关于vue-cli4:vuecli4-目录结构介绍

一、应用vue-cli4 脚手架初始化我的项目后,目录构造如下: ├── README.md├── babel.config.js├── node_modules├── package.json├── public│   ├── favicon.ico│   └── index.html├── src│   ├── App.vue│   ├── assets│   │   └── logo.png│   ├── components│   │   └── HelloWorld.vue│   ├── main.js│   ├── router│   │   └── index.js│   ├── store│   │   └── index.js│   └── views│   ├── About.vue│   ├── Home.vue│   └── video│   └── clip│   ├── class│   │   └── list.js│   ├── clip.vue│   └── data.json├── vue.confog.js└── yarn.lock二、目录介绍 README.md 我的项目介绍node_modules 相干依赖package.json 项目名称,所须要模块、版本、运行命令public 寄存动态目录。public上面的文件会一成不变的增加到dist中,不会被合并、压缩;不会被webpack打包工具所解决,多用来寄存第三方插件。相似于vue2中的 static 目录。所以想要援用,必须应用绝对路径.public/index.html 模板文件,生成我的项目的入口文件,打包后的js、css主动注入到该页面src 寄存各种vue文件的中央src/assets 用于寄存各种动态文件,如图片,css。编译之后,assets目录中的文件,会被合并到一个文件中,而后进行压缩。多用来寄存业务级的js、css等,如一些全局的scss款式文件、全局的工具类js文件。图片的援用形式只能通过:<img class="logo" src="@/assets/logo.png" alt="" />形式援用。src/compnents 寄存公共组件src/views 寄存页面级页面src/App.vue 主vue组件 引入其余组件,App.vue是我的项目的主组件。src/main.js 入口文件,初始化vue实例,也能够在此援用组件库或者全局变量src/router.js 路由文件,各个页面的路由src/store.js 状态文件

August 12, 2021 · 1 min · jiezi

关于vue-cli4:vue创建项目css版本问题

明天在开发时,装置插件,后续不晓得咋的报如下错:google好多说css\less\sass短少依赖导致的,依照他们提醒装置完依赖还是没解决,起初找到答案:npm install -D vue-style-loader --registry https://registry.npm.taobao.org就行了。仅作为笔记(相干文章:https://www.jianshu.com/p/d7b...

April 28, 2021 · 1 min · jiezi

关于vue-cli4:VueCli40安装及项目框架的搭建

装置版本npm install -g @vue/cliyarn global add @vue/clivue --version 查看版本 如果呈现上面状况1、如果应用npm装置,应用命令npm root -g查看npm包的地位2、如果应用yarn装置,应用命令yarn global dir查看yarn装置的地位3、关上环境变量中的零碎变量,找到path变量进行编辑增加 创立我的项目vue create mall //(创立名称为mall的我的项目)cd mallyarn add axiosyarn add vue-routeryarn add vuex在main.js文件中增加 import axios from 'axios'import VueRouter from 'vue-router'import Vuex from 'vuex'Vue.prototype.$axios = axios;Vue.use(VueRouter)Vue.use(Vuex)装置vue-devtools拓展工具vue-devtools官网点击关上,下载master上的代码解压进入此目录执行命令npm installnpm run build再通过浏览器的扩大程序进行加载shell/chrome 跨域计划1、通过CORS进行跨域(后端批改)2、通过jsonp进行跨域 import jsonp from 'jsonp'jsonp('https://www.imooc.com/common/adver-getadver',(err,res)=>{ console.log(res)})3、接口代理-通过批改nginx服务器配置来实现 jsonp('/api/activity/servicetime',(err,res)=>{ console.log(res)})新建vue.config.js文件,与package.json同级 module.exports = { devServer:{ host:"localhost", port:8080, proxy:{//事件代理 '/api':{ target:'https://www.imooc.com', changeOrigin:true, pathRewrite:{ '/api':'' } } } }}插件装置//装置图片懒加载、element-ui、sass、轮播yarn add vue-lazyload element-ui node-sass sass-loader vue-awesome-swiper vue-axios vue-cookiestorage封装storage自身有api,然而只是简略的key/value模式storage只存储字符串,须要手工转化成json对象storage只能一次性清空,不能单个清空/** * Storage封装 */ const STORAGE_KEY = 'mall';export default { // 存储值 setItem(key, value, module_name) { if (module_name) { let val = this.getItem(module_name); val[key] = value; this.setItem(module_name, val); } else { let val = this.getStorage(); val[key] = value; window.sessionStorage.setItem(STORAGE_KEY, JSON.stringify(val)); } }, // 获取某一个模块上面的属性user上面的userName getItem(key, module_name) { if (module_name) { let val = this.getItem(module_name); if (val) return val[key]; } return this.getStorage()[key]; }, getStorage() { return JSON.parse(window.sessionStorage.getItem(STORAGE_KEY) || '{}'); }, clear(key, module_name) { let val = this.getStorage(); if (module_name) { if (!val[module_name]) return; delete val[module_name][key]; } else { delete val[key]; } window.sessionStorage.setItem(STORAGE_KEY, JSON.stringify(val)); }}接口谬误拦挡import Vue from 'vue'import App from './App.vue'import axios from 'axios'import VueAxios from 'vue-axios'import VueRouter from 'vue-router'import Vuex from 'vuex'import router from './router.js'//依据前端的跨域形式做调整axios.defaults.baseURL = '/api';axios.defaults.timeout = 8000;//接口谬误拦挡axios.interceptors.response.use(function (response){ let res = response.data; if(res.status == 0){//接口胜利返回的状态值为 0 return res.data }else if(res.status == 10){//未登录接口返回的状态值为 10 window.location.href = '/#/login' }else{ alert(res.msg); }})Vue.config.productionTip = falseVue.use(VueRouter)Vue.use(Vuex)Vue.use(VueAxios, axios)new Vue({ router, render: h => h(App),}).$mount('#app')

October 12, 2020 · 2 min · jiezi

关于vue-cli4:VueCli40安装及创建项目

装置版本npm install -g @vue/cliyarn global add @vue/clivue --version 查看版本 如果呈现上面状况1、如果应用npm装置,应用命令npm root -g查看npm包的地位2、如果应用yarn装置,应用命令yarn global dir查看yarn装置的地位3、关上环境变量中的零碎变量,找到path变量进行编辑增加 创立我的项目vue create mall //(创立名称为mall的我的项目)cd mallyarn add axiosyarn add vue-routeryarn add vuex在main.js文件中增加 import axios from 'axios'import VueRouter from 'vue-router'import Vuex from 'vuex'Vue.prototype.$axios = axios;Vue.use(VueRouter)Vue.use(Vuex)装置vue-devtools拓展工具vue-devtools官网点击关上,下载master上的代码解压进入此目录执行命令npm installnpm run build再通过浏览器的扩大程序进行加载shell/chrome

October 10, 2020 · 1 min · jiezi