Coder Social home page Coder Social logo

pfan123 / front-end-navigator Goto Github PK

View Code? Open in Web Editor NEW
137.0 6.0 21.0 2.52 MB

前端导航平台--收录前端业内优秀技术博客、框架,方便快速查找

Home Page: https://docs.pfan123.com/

License: MIT License

JavaScript 67.39% Vue 28.71% CSS 2.84% HTML 1.06%

front-end-navigator's Introduction

前端导航平台简介

是否有过当你看到比较优秀的前端资源时,由于没有时间来的及收录,过段时间等需要的时,却翻来覆去不知道去哪了~~ 前端导航站,收集前端业内优秀技术博客、框架,方便快速寻找优秀资源,~~宝宝再也不用担心查找资源了~~

前端导航平台由来

记得2015年时,当我为查找资料而烦恼时,时间久了容易忘记时,为了方便自己记忆以备后用,简单的搭了 前端开发导航平台(其实就是一静态页面展示,手动在页面上添加数据),但随着时间过去,前端圈的变化,以及工作的忙碌,后来越来越懒得去手动添加,感觉异常的麻烦,一直是自己想解决的一个问题。最近,抽了一个周末,把平台重新重构了一遍,优化了预览导航,以及增加简单的管理,NEW 前端开发导航平台

前端导航首页

前端导航登录页面

前端导航管理页面

平台重构涉及技术点

技术架构: webpack2+vue2+vue-router2+leancloud+Mockjs

  • 1.构建webpack2.0多页面应用
  • 2.vue2数据渲染,实践父、子组件通信,组件与组件之间通信
  • 3.vue-router2、axios实现控制管理页面路由
  • 4.leancloud数据云存储
  • 5.Mockjs开发过程中模拟测试数据

规范提交:husky + validate-commit-msg + conventional-changelog

husky

validate-commit-msg

conventional-changelog

Git commit message和工作流规范

知乎Commit message提交格式

收录前端资源

移动端开发资源

前端导航平台数据列表

导航目录结构:

  • 前端圈子社区
  • 前端规范文档
  • 移动端开发资源
  • 图片优化
  • CSS3动画
  • JS动画引擎
  • JS游戏框架
  • MVVM框架
  • 浏览器检测工具
  • 图表工具
  • 图标工具
  • 前端安全
  • 前端自动化
  • 桌面端开发
  • 设计资源
  • 开发工具技巧
  • 优秀博客/资料
  • 前端面试资料
  • 前端导航平台

使用方式

1.拉取仓库

git clone [email protected]:o2team/wxapp-market.git

2.执行命令

yarn run app  //启动 webpack-dev-server  执行 webpack.config.js
yarn run dev  //启动 webpack-dev-server  执行 webpack.dev.config.js
yarn run prod  //启动 webpack-dev-server  执行 webpack.dev.prod.js
npm run analyzer //执行 analyzer

img

技术实践文章

webpack简介与使用

从 webpack v1 迁移到 webpack v2 新特性

webpack2 使用优化

Webpack插件中CommonsChunkPlugin 与 ExtractTextPlugin

webpack插件开发

vue数据更新, 视图未更新

Vue 2.0组件通信

Vuex2.0 状态管理

Vue2.0 中 render 和 template 疑惑点

webpack 3: Official Release

webpack 2: Github

参考案例

腾讯前端导航

圈子

前端网址导航-haorooms导航

webpack更新构建优化

webpack-uglify-parallel多线程并行压缩代码,提高效率

- new webpack.optimize.UglifyJsPlugin({
-   exclude:/\.min\.js$/
-   mangle:true,
-   compress: { warnings: false },
-   output: { comments: false }
- })

+ new UglifyJsParallelPlugin({
+  workers: os.cpus().length,
+  mangle: true,
+  compressor: {
+    warnings: false,
+    drop_console: true,
+    drop_debugger: true
+   }
+ })

webpack-bundle-analyzer将内容束展示为方便交互的树状图的Webpack插件和CLI实用工具。

DllPlugin 与 DllReferencePlugin 使用DllPlugin和DllReferencePlugin预编译, 通过前置这些依赖包的构建,来提高真正的 build 和 rebuild 的构建效率。

new webpack.DllPlugin({
    path: path.join(APP_PATH, 'manifest.json'),
	name: "[name]_library",
	context: __dirname
})

new webpack.DllReferencePlugin({
	context: __dirname,
	manifest: require(path.join(APP_PATH, 'manifest.json'))
})

sw-precache-webpack-plugin工具,生成service-worker caches列表

sw-toolbox 预缓存 Precaching,构建阶段检测任何本地资源是否已更改,自动更新缓存列表

sw-precache 运行时缓存 Runtime caching,不提供额外的缓存更新机制,需要设置匹配文件的请求并使用适当的处理 程序的路由

更新升级到webpack 3.1

问题1

DeprecationWarning: Chunk.modules is deprecated. Use Chunk.getNumberOfModules/mapModules/forEachModule/containsModule instead. 错误是由于 extract-text-webpack-plugin 引起,由于webpack升级到3.0之后,改变了引入extract-text-webpack-plugin参数的形式, 解决方案 升级 [email protected] + [email protected], 同时更改extract-text-webpack-plugin参数方式

问题2

parseQuery() will be replaced with getOptions() in the next major version of loader-utils 此问题,是在[email protected]里面出现由file-loader or url-loader导致,更新到[email protected]可以解决

问题3

由于 Babel 默认只转换转各种 ES2015 语法,而不转换新的 API,比如 Promise,以及Object.assign、Array.from 这些新方法,这时我们需要提供一些 ployfill 来模拟出这样一个提供原生支持功能的浏览器环境。 主要有两种方式:babel-runtime 和 babel-polyfill

问题4

引入happypack多进程构建,提升构建效率。配置 new HappyPack, 提示报错HappyPack: plugin for the loader '1' could not be found 必须要增加new HappyPack({id:1}),有点不明白 解决问题,是由于替换当前loader未去掉其中options导致

test: /\.js$/,
exclude: /node_modules/,  //排除node_modules文件夹
use: {
  loader: 'happypack/loader?id=js'
-  options: {
-     presets: ['es2015','stage-2']
-  }
},  

new HappyPack({
	id: 'js',
	//注意参数
+	loaders: [ 'babel-loader?cacheDirectory=true&presets[]=es2015&presets[]=stage-2' ],  
	threadPool: happyThreadPool,
	cache: true,
	verbose: true        
})          

问题5

在linux下执行sh文件时提示下面信息: -bash: ./xx.sh: Permission denied 出现情况是由于,文件权限导致,chmod 777 xx.sh即可

问题6

vue.common.js 与 vue.runtime.js 区别

  • 独立构建包括编译和支持 template 选项。 它也依赖于浏览器的接口的存在,所以你不能使用它来为服务器端渲染。

    <div id="app">
    	<banner></banner>
    	<contain></contain>
    </div>
    
  • 运行时构建不包括模板编译,不支持 template 选项。运行时构建,可以用 render 选项,但它只在单文件组件中起作用,因为单文件组件的模板是在构建时预编译到 render 函数中,运行时构建只有独立构建大小的 30%,只有 16Kb min+gzip 大小。

<div id="app">
</div>
import APP from './app.vue'
new Vue({
  render: (createElement) => {
    return createElement(APP)
  }
}).$mount('#app')

基于webpack Code Splitting实现react组件的按需加载

Babel下的ES6兼容性与规范

使用 ES6 的浏览器兼容性问题

Bable polyfill

Babel polyfill 知多少

Babel 用户手册

License

This content is released under the MIT License.

front-end-navigator's People

Contributors

pfan123 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

front-end-navigator's Issues

Webpack插件中CommonsChunkPlugin 与 ExtractTextPlugin

CommonsChunkPlugin

CommonsChunkPlugin 插件,是一个可选的用于建立一个独立文件(又称作 chunk)的功能,这个文件包括多个入口 chunk 的公共模块。通过将公共模块拆出来,最终合成的文件能够在最开始的时候加载一次,便存起来到缓存中供后续使用。这个带来速度上的提升,因为浏览器会迅速将公共的代码从缓存中取出来,而不是每次访问一个新页面时,再去加载一个更大的文件。

CommonsChunkPlugin配置

{
  name: string, // or
  names: string[],
  // 这是 common chunk 的名称。已经存在的 chunk 可以通过传入一个已存在的 chunk 名称而被选择。
  // 如果一个字符串数组被传入,这相当于插件针对每个 chunk 名被多次调用
  // 如果该选项被忽略,同时 `options.async` 或者 `options.children` 被设置,所有的 chunk 都会被使用,否则 `options.filename` 会用于作为 chunk 名。

  filename: string,
  // common chunk 的文件名模板。可以包含与 `output.filename` 相同的占位符。
  // 如果被忽略,原本的文件名不会被修改(通常是 `output.filename` 或者 `output.chunkFilename`)

  minChunks: number|Infinity|function(module, count) -> boolean,
  // 在传入  公共chunk(commons chunk) 之前所需要包含的最少数量的 chunks 。
  // 数量必须大于等于2,或者少于等于 chunks的数量
  // 传入 `Infinity` 会马上生成 公共chunk,但里面没有模块。
  // 你可以传入一个 `function` ,以添加定制的逻辑(默认是 chunk 的数量)

  chunks: string[],
  // 通过 chunk name 去选择 chunks 的来源。chunk 必须是  公共chunk 的子模块。
  // 如果被忽略,所有的,所有的 入口chunk (entry chunk) 都会被选择。


  children: boolean,
  // 如果设置为 `true`,所有  公共chunk 的子模块都会被选择

  async: boolean|string,
  // 如果设置为 `true`,一个异步的  公共chunk 会作为 `options.name` 的子模块,和 `options.chunks` 的兄弟模块被创建。
  // 它会与 `options.chunks` 并行被加载。可以通过提供想要的字符串,
  // 而不是 `true` 来对输出的文件进行更换名称。

  minSize: number,
  // 在 公共chunk 被创建立之前,所有 公共模块 (common module) 的最少大小。
}

ExtractTextWebpackPlugin

ExtractTextWebpackPlugin会将所有的入口 chunk(entry chunks)中引用的 *.css,移动到独立分离的 CSS 文件。因此,你的样式将不再内嵌到 JS bundle 中,而是会放到一个单独的 CSS 文件(即 styles.css)当中。 如果你的样式文件大小较大,这会做更快提前加载,因为 CSS bundle 会跟 JS bundle 并行加载。

优点 缺点
更少 style 标签 (旧版本的 IE 浏览器有限制) 额外的 HTTP 请求
CSS SourceMap (使用 devtool: "source-map" 和 extract-text-webpack-plugin?sourceMap 配置) 更长的编译时间
CSS 请求并行 没有运行时(runtime)的公共路径修改
CSS 单独缓存 没有热替换
更快的浏览器运行时(runtime) (更少代码和 DOM 操作) ……

ExtractTextWebpackPlugin用法

const ExtractTextPlugin = require("extract-text-webpack-plugin");

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ExtractTextPlugin.extract({
          fallback: "style-loader",
          use: "css-loader"
        })
      }
    ]
  },
  plugins: [
    new ExtractTextPlugin("styles.css"),
  ]
}

更多详情,参考

CommonsChunkPlugin 与 ExtractTextWebpackPlugin 同时使用问题

实例:

  module.exports.module.rules =  (module.exports.module.rules || []).concat([
      //ExtractTextPlugin 与预览输出css不能同时存在
      {
        test: /\.(css|scss)$/,
        //https://github.com/webpack-contrib/extract-text-webpack-plugin
        use: ExtractTextPlugin.extract({
             fallback: 'style-loader',
             use: ['css-loader', "postcss-loader", "sass-loader"]
        })        
        ,
        include: [
          APP_SASS
        ]        
      }
  ])
  
  module.exports.plugins = (module.exports.plugins || []).concat([
	  new ExtractTextPlugin( './css/[name].css'),
	  new webpack.optimize.CommonsChunkPlugin({
	      name: 'vendors', // 将公共模块提取,生成名为`vendors`的chunk
	      chunks: Object.keys(entries),
	      // minChunks: Infinity //传入 `Infinity` 会马上生成 公共chunk,但里面没有模块
	      minChunks: Object.keys(entries).length // 会提取所有entry共同依赖的模块
	  })  
  ])	  

当在入口 entry 脚本中,require('xxx.css')或者import style from 'xxx.css',会导致 'CommonsChunkPlugin' 提取公共模块,页面脚本报错,猜测提取公共样式模块引起报错,而将minChunks 设置不为Object.keys(entries).length或Infinity会马上生成 公共chunk里面没有模块,没有根本上面分离提取公共模块。

vue数据更新, 视图未更新

vue数据更新, 视图未更新

在使用 vue 过程中,可能经常有遇到 vm.items[i] = xxx 修改数据model之后,视图未更新重新渲染问题,基于这个问题:

Vue.js 不能检测到下面数组变化:

  • 1.直接用索引设置元素,如 vm.items[indexOfItem] = newValue;

  • 2.修改数据的长度,如 vm.items.length = newLength。

Vue.js 1.0

为了以上问题, 扩展了观察数组,为它添加了 $set()$remove() 方法:

$set() 方法

// 与 `example1.items[0] = ...` 相同,但是能触发视图更新
example1.items.$set(0, { childMsg: 'Changed!'})

$remove() 方法, 用于从目标数组中查找并删除元素,在内部它调用 splice(), 那么:

var index = this.items.indexOf(item)
if (index !== -1) {
  this.items.splice(index, 1)
}

//以上代码可以用这行替换
this.items.$remove(item)

Vue.js 2.0

1.解决第一种情况

// Vue.set
Vue.set(example1.items, indexOfItem, newValue)

// Array.prototype.splice`
example1.items.splice(indexOfItem, 1, newValue)

2.解决第二种情况直接使用 splice

example1.items.splice(newLength)

Vue.js 对于数组变动检测,还包装了被观察数组的变异方法。

数组变动检测

变异方法

Vue.js 包装了被观察数组的变异方法,故它们能触发视图更新。被包装的方法有:

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

小知识: 其实是改变原有数组,整体变为改变属性变更。

重塑数组

变异方法(mutation method),顾名思义,会改变被这些方法调用的原始数组。相比之下,也有非变异(non-mutating method)方法,例如: filter(), concat(), slice()。这些不会改变原始数组,但总是返回一个新数组。当使用非变异方法时,可以用新数组替换旧数组:

Vue1.0 数组更新检测

Vue2.0 数组更新检测

Vue2.0 中 render 和 template 疑惑点

从 Vue 升级到2.0之后,多了采用jsx方式渲染生成HTML模版,还有一种就是一直沿用的 template 字符串拼接方式生成模版,但其实隐含的还有 直接去挂载手动写入模版,Vue 的功能很强大多种方式有时也让我们感到到很😅

Vue2.0 生成 HTML 方式:

  • 1.使用 render 函数jsx方式渲染生成HTML模版
  • 2.使用 template 字符串拼接方式生成模版
  • 3.采用自定义标签,内嵌到 Vue 根实例挂载点(自定义标签影响html语义化,不推荐,但其实这个算是vue 1.0 采用 es5 写法遗留问题未借用babel)

注意: 对于挂载实例 不是采用 render 方式拼接模版,webpack 打包 vue 会报错,主要是由于webpack选择 vue 版本问题,详见 https://github.com/vuejs-templates/webpack/issues/215,[2.0 Changes #2873](vuejs/vue#2873)

警告错误 [Vue warn]: You are using the runtime-only build of Vue where the template option is not available. Either pre-compile the templates into render functions, or use the compiler-included build.

在解释这些之前,我们先搞清楚明白,组件 component 与 根实例 new Vue() 的关系:

创建 Vue 的根实例

const vm = new Vue({
  // 选项对象

  data: {},
  template: '<my-component></<my-component>',
  //render: (myComponent) => {
 	   return createElement(myComponent)
 	},

  components: {
  	"my-component": MyComponent 
  },

  created () => {

  },

  mounted () => {

  },

  methods () => {

  }

})

一个 Vue 实例其实正是一个 MVVM 模式中所描述的 ViewModel - 因此在文档中经常会使用 vm 这个变量名。
在实例化 Vue 时,需要传入一个选项对象,它可以包含数据、模板、挂载元素、方法、生命周期钩子等选项。

创建 component 组件

可以扩展 Vue 构造器,从而用预定义选项创建可复用的组件构造器(这个是官方说法,比较绕口),其实说白了,组件可以理解为继承于 Vue 构造器,与跟实例 vm 存在细微的差别对数据指针data更改。

//继承Vue 构造器,创建组件,区别修改data指针,跟实例 data: {},组件 data () {return {}} 
const MyComponent = Vue.extend({
  // 扩展选项对象
})

// 所有的 `MyComponent` 实例都将以预定义的扩展选项被创建,实例组件可以直接 data: {}, 没有指针问题,不会影响其他组件
const myComponentInstance = new MyComponent({
  data: {}
})

注册 component 组件

组件全局注册

// 要使用这个组件构造器做的组件,需要用 Vue.component(tag, consturctor) 注册--全局注册,注册在根实例上的,全局可以直接使用
// Vue.component('my-component', MyComponent)

注意:对于统一性、共用性组件,建议采用组件全局注册方式,如 <ant-img src = "" v-on:error="_errorReport()" v-on:load="_loadReport"></ant-img>替代image标签进行统一上报处理。

组件局部注册

// vue 创建组件默认,使用构造器,然后实例生成组件
const MyComponent = Vue.extend({
  
})

const myComponentInstance = new MyComponent({
	data: {},
	components: {
	  "my-component": MyComponent  //组件局部注册,注册在子组件上的
	}
})

有了以上知识之后,基本对vue的实例,组件思路有了整理的了解,那接下来理解 Vue2.0 生成 HTML 方式。

render 函数jsx方式渲染生成HTML模版

字符串模板的代替方案,允许你发挥 JavaScript 最大的编程能力。render 函数接收一个 createElement 方法作为第一个参数用来创建 VNode

//根实例挂载
const vm = new Vue({
	//virtul Dom 方案渲染模版
	render: h => h(APP)

	//render: (createElement) => {
	//	 return createElement(APP)
	//}	
}).$mount('#app')

createElement 函数中生成模板:

createElement(
  // {String | Object | Function}
  // 一个 HTML 标签,组件选项,或一个函数
  // 必须 Return 上述其中一个
  'div',
  // {String | Array}
  // Children VNodes, built using `createElement()`,
  // or simply using strings to get 'text VNodes'. Optional.
  [
    'Some text comes first.',
    createElement('h1', 'A headline'),
    createElement(MyComponent, {
      props: {
        someProp: 'foobar'
      }
    })
  ]
)

template 字符串拼接方式生成模版

    // Vue.extend()组件构造器
    const MyComponent = Vue.extend({
      template: '<div>大家好,{{msg}}我来了</div>',
      data: function () {
        return {
          msg: 'Hello!'   //组件构造器生成的组件data数据需要return 返回,而实例new Vue()不需要(主要是处理指针问题)
        }
      },
      created: function(){
        console.log("组件开始创建")
      }
    })

    const vm = new Vue({
    	//template是字符串模版拼接方案渲染模版
    	template: '<my-component></my-component>',
	    components: {
	       "my-component": MyComponent  //实例局部注册组件
	    },
	    created(){
	    	console.log("开始创建")
	    }

    })

采用自定义标签,内嵌到 Vue 根实例挂载点获取模版

index.html

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
  <meta name="author" content="@pfan"/>
</head>

    <!-- S 左侧导航内容 -->
    <div vm-mod = "sideLeftNav">
      <my-component></my-component>
    </div>
    <!-- E 左侧导航内容 -->

    <!-- 这里填写路径是输出的路径 相对于dist输出路径 -->
    <!-- <script src="./app.js"></script> -->
  </body>
</html>
 

app.js

import Vue from 'vue'

var MyComponent = Vue.extend({
  template: '<div>大家好,{{msg}}我来了</div>',
  data: function () {
    return {
      msg: 'Hello!'  
    }
  },
  created: function(){
    console.log("组件开始创建")
  }
})

//全局注册,不需要在组件做局部注册
Vue.component('my-component', MyComponent)

const vm = new Vue({
	el: '[vm-mod="sideLeftNav"]', 

	//由于组件是全局注册,所以不需要局部注册,可直接使用
	components: {
	//	"my-component": MyComponent  //实例局部注册组件
	}
})

ps: 注意,自定义标签的这种模版方式不推荐使用,影响html语义化。

总结,通过以上的例子,我们理清了,组件与 Vue 根实例的关系, 以及挂载点,生成 html 的方式,最后更好的扩展优化可以深入做vue组件直出方案 prerender-spa-plugin 做简单直出。

参考资料:

官方 Vue.js 教程
极客 Vue.js 教程
Vue 组件 data 为什么必须是函数?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.