SegmentFault 前端进阶日记最新的文章
2017-04-23T11:35:16+08:00
https://segmentfault.com/feeds/blogs
https://creativecommons.org/licenses/by-nc-nd/4.0/
treer:命令行生成目录结构的实用小工具
https://segmentfault.com/a/1190000009163772
2017-04-23T11:35:16+08:00
2017-04-23T11:35:16+08:00
Derycktse
https://segmentfault.com/u/derycktse
1
<p>有时候在写说明文档的时,需要列出文件的一个目录结构,几次手动拼接之后,写了一个cli小工具来自动生成。</p>
<h3>安装方法:</h3>
<pre><code>$ npm install treer -g</code></pre>
<p>如此我们便可以快速的生成目录结构啦!</p>
<h3>生成结果</h3>
<pre><code>$ treer
Desktop
├─.DS_Store
├─.localized
├─dir2
| ├─file3
| └file4
├─dir1
| ├─dile2
| └file1</code></pre>
<h4>指定目录</h4>
<p>默认的目录为当前的路径,可以通过<code>-d</code> 传入指定的路径</p>
<pre><code>$ treer -d <指定路径></code></pre>
<h4>导出结果</h4>
<p>可将结果导出到文件中</p>
<pre><code>$ treer -e <导出路径></code></pre>
<h4>忽略指定的目录</h4>
<p>有时候我们需要忽略一些文件名,比如我们的<code>node_modules</code>文件夹</p>
<pre><code>$ treer -i <"文件名,支持正则表达式/regex/哦"></code></pre>
<p>如果觉得实用,不妨<a href="https://link.segmentfault.com/?enc=3aRLbXIuMjzBXdmeRCcHuQ%3D%3D.gBaYZy%2BeczHAesl2pfGuhTcH39RogXYZ2KxwlhXuMb7J%2B7JoC5dzC7cqvyV77o8t" rel="nofollow">Star</a>一下吧,<a href="https://link.segmentfault.com/?enc=TEuCFb8Z13zPYkpAp1fs5A%3D%3D.8UVsJJRxfCnt6DOwZTM0YIulHnzoWLXUrUolP2JTouVHGexy2JTQ1Aa6KYHuOUmD" rel="nofollow">github地址</a></p>
webpack入门
https://segmentfault.com/a/1190000008542435
2017-03-02T14:50:30+08:00
2017-03-02T14:50:30+08:00
Derycktse
https://segmentfault.com/u/derycktse
0
<h2>什么是webpack</h2>
<p>webpack是一个module bundler,可以将把有依赖关系的各种文件打包成一系列的静态资源</p>
<h2>安装</h2>
<p>首先我们安装最新版的webpack, 我安装的版本是2.2.1</p>
<pre><code>npm install -g webpack</code></pre>
<p>下面我们将探讨webpack 2 的使用</p>
<p>我们可以直接在终端中使用webpack,命令如下</p>
<pre><code>webpack {源文件/入口文件} {目标文件}
webpack --watch //监听模式
webpack -p //混淆脚本 </code></pre>
<p>考虑到随着我们项目复杂度的增高,有可能我们的配置选项也会很多,所以,我们完全可以将配置放到文件中, webpack在执行的时候默认会加载webpack.config.js文件作为配置, 如果我们需要指定配置文件的话,方法如下:</p>
<pre><code class="terminal">webpack --config {配置文件}</code></pre>
<p>我们来看下webpack都有哪些配置:</p>
<pre><code class="js">//webpack.config.js
const path = require('path');
module.exports = {
// click on the name of the option to get to the detailed documentation
// click on the items with arrows to show more examples / advanced options
entry: "./app/entry", // string | object | array
// Here the application starts executing
// and webpack starts bundling
output: {
// options related to how webpack emits results
path: path.resolve(__dirname, "dist"), // string
// the target directory for all output files
// must be an absolute path (use the Node.js path module)
filename: "bundle.js", // string
// the filename template for entry chunks
publicPath: "/assets/", // string
// the url to the output directory resolved relative to the HTML page
library: "MyLibrary", // string,
// the name of the exported library
libraryTarget: "umd", // universal module definition
// the type of the exported library
/* Advanced output configuration (click to show) */
},
module: {
// configuration regarding modules
rules: [
// rules for modules (configure loaders, parser options, etc.)
{
test: /\.jsx?$/,
include: [
path.resolve(__dirname, "app")
],
exclude: [
path.resolve(__dirname, "app/demo-files")
],
// these are matching conditions, each accepting a regular expression or string
// test and include have the same behavior, both must be matched
// exclude must not be matched (takes preferrence over test and include)
// Best practices:
// - Use RegExp only in test and for filename matching
// - Use arrays of absolute paths in include and exclude
// - Try to avoid exclude and prefer include
issuer: { test, include, exclude },
// conditions for the issuer (the origin of the import)
enforce: "pre",
enforce: "post",
// flags to apply these rules, even if they are overridden (advanced option)
loader: "babel-loader",
// the loader which should be applied, it'll be resolved relative to the context
// -loader suffix is no longer optional in webpack2 for clarity reasons
// see webpack 1 upgrade guide
options: {
presets: ["es2015"]
},
// options for the loader
},
{
test: "\.html$",
use: [
// apply multiple loaders and options
"htmllint-loader",
{
loader: "html-loader",
options: {
/* ... */
}
}
]
},
{ oneOf: [ /* rules */ ] },
// only use one of these nested rules
{ rules: [ /* rules */ ] },
// use all of these nested rules (combine with conditions to be useful)
{ resource: { and: [ /* conditions */ ] } },
// matches only if all conditions are matched
{ resource: { or: [ /* conditions */ ] } },
{ resource: [ /* conditions */ ] }
// matches if any condition is matched (default for arrays)
{ resource: { not: /* condition */ } }
// matches if the condition is not matched
],
/* Advanced module configuration (click to show) */
},
resolve: {
// options for resolving module requests
// (does not apply to resolving to loaders)
modules: [
"node_modules",
path.resolve(__dirname, "app")
],
// directories where to look for modules
extensions: [".js", ".json", ".jsx", ".css"],
// extensions that are used
alias: {
// a list of module name aliases
"module": "new-module",
// alias "module" -> "new-module" and "module/path/file" -> "new-module/path/file"
"only-module$": "new-module",
// alias "only-module" -> "new-module", but not "module/path/file" -> "new-module/path/file"
"module": path.resolve(__dirname, "app/third/module.js"),
// alias "module" -> "./app/third/module.js" and "module/file" results in error
// modules aliases are imported relative to the current context
},
/* alternative alias syntax (click to show) */
/* Advanced resolve configuration (click to show) */
},
performance: {
hints: "warning", // enum
maxAssetSize: 200000, // int (in bytes),
maxEntrypointSize: 400000, // int (in bytes)
assetFilter: function(assetFilename) {
// Function predicate that provides asset filenames
return assetFilename.endsWith('.css') || assetFilename.endsWith('.js');
}
},
devtool: "source-map", // enum
// enhance debugging by adding meta info for the browser devtools
// source-map most detailed at the expense of build speed.
context: __dirname, // string (absolute path!)
// the home directory for webpack
// the entry and module.rules.loader option
// is resolved relative to this directory
target: "web", // enum
// the environment in which the bundle should run
// changes chunk loading behavior and available modules
externals: ["react", /^@angular\//],
// Don't follow/bundle these modules, but request them at runtime from the environment
stats: "errors-only",
// lets you precisely control what bundle information gets displayed
devServer: {
proxy: { // proxy URLs to backend development server
'/api': 'http://localhost:3000'
},
contentBase: path.join(__dirname, 'public'), // boolean | string | array, static file location
compress: true, // enable gzip compression
historyApiFallback: true, // true for index.html upon 404, object for multiple paths
hot: true, // hot module replacement. Depends on HotModuleReplacementPlugin
https: false, // true for self-signed, object for cert authority
noInfo: true, // only errors & warns on hot reload
// ...
},
plugins: [
// ...
],
// list of additional plugins
/* Advanced configuration (click to show) */
}</code></pre>
<p>下面我们来创建一个简单的项目<br>我们的项目结构如下</p>
<pre><code>.
├── dist
├── src
│ └── entry.js
├── index.html
└── webpack.config.js</code></pre>
<p>index.html</p>
<pre><code><!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<script src="./dist/bundle.js"></script>
</body>
</html></code></pre>
<p>src/entry.js</p>
<pre><code>document.write('hello world')</code></pre>
<p>webpack.config.js</p>
<pre><code>const path = require('path')
module.exports = {
entry: './src/entry.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
}
}</code></pre>
<p>在终端下运行命令:</p>
<pre><code>webpack --watch</code></pre>
<p>使用<a href="https://link.segmentfault.com/?enc=C7QJEGTruDaT%2B9yPOv76Og%3D%3D.peEoH0a25Uz7a4MU7%2B6zFOgO647mfC1hQBd873OmqgvfKzRXx2ifz%2FPnOkRITvAV" rel="nofollow">http-server</a>起一个本地服务</p>
<pre><code>http-server -p 8080</code></pre>
<p>可以看到,entry.js的内容被打包到了bundle.js 中<br>这是webpack最简单的应用,下面我们来看看如何使用loader</p>
<h2>loader</h2>
<p>webpack2中已经集成了<a href="https://link.segmentfault.com/?enc=ek%2BqNllNlimsTty5iPnU%2Bg%3D%3D.ycLMUsH6TSCAFbx435rmSDJQpmuRNZxn5TPd7UcWt4Lu%2Fp9vzyqnz0A3U31P1dXeEuPQ83dZUsRYCHoyW53FmuZk%2B%2FDZiWQFEZlum4hEW18%3D" rel="nofollow">json-loader</a>, 所以我们无需安装其他的依赖<br>在src中增加hello.json文件</p>
<pre><code class="json">{"greet" : "hello from json"}</code></pre>
<p>修改<code>entry.js</code></p>
<pre><code class="javascript">import json from './hello.json'
document.write(json.greet)</code></pre>
<p>刷新<a href="https://link.segmentfault.com/?enc=ya5WCIRmadI95kHJexF7ZQ%3D%3D.%2FKHJ9P2JhS9W3wH0XoGft7oodquh%2BQD%2BdsrflpqND5w%3D" rel="nofollow">http://127.0.0.1:8080/</a><br>可以看到hello.json的结果已经输出到浏览器中</p>
<h4>使用其他loader</h4>
<p>如果其他格式的文件,比如css文件我们可以使用相应的loader来解析,安装依赖</p>
<pre><code>npm install --save-dev style-loader css-loader</code></pre>
<p>修改<code>webpack.config.js</code></p>
<pre><code>const path = require('path')
module.exports = {
entry: './src/entry.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
rules: [{
test: /\.css$/,
use: ["style-loader", "css-loader"]
}]
}
}</code></pre>
<p>entry.js</p>
<pre><code>import './main.css'
import json from './hello.json'
document.write(json.greet)</code></pre>
<p>可以看到,main.css也经过loader的解析而打包进bundle.js里面了</p>
webpack使用require.ensure进行代码分割
https://segmentfault.com/a/1190000008514679
2017-02-28T15:46:05+08:00
2017-02-28T15:46:05+08:00
Derycktse
https://segmentfault.com/u/derycktse
2
<h2>代码分割</h2>
<p>实例来自于<a href="https://link.segmentfault.com/?enc=P%2FN5U7wLyrB1PQJ2kGHGRA%3D%3D.dugRTS0TaHOQdGU%2BdiOap4phjF9lLvE8ObHHxy2%2BjHgShHJC4f1sSemIjzFnmA%2F%2BmJIeGhOJ7oURzaEwyi7D7g%3D%3D" rel="nofollow">webpack</a><br>假定我们有下面的项目结构</p>
<pre><code>.
├── dist
├── js
│ ├── a.js
│ ├── b.js
│ ├── c.js
│ └── entry.js
└── webpack.config.js</code></pre>
<p>文件内容<br>entry.js</p>
<pre><code>require('./a');
require.ensure(['./b'], function(require){
require('./c');
console.log('done!');
});</code></pre>
<p>a.js</p>
<pre><code>console.log('***** I AM a *****');</code></pre>
<p>b.js</p>
<pre><code>console.log('***** I AM b *****');</code></pre>
<p>c.js</p>
<pre><code>console.log('***** I AM c *****');</code></pre>
<p>下面我们看一下<code>webpack.config.js</code>的配置</p>
<pre><code class="javascript">const path = require('path')
module.exports = {
entry : './js/entry.js'
,
output : {
filename : 'bundle.js'
, path : path.resolve(__dirname, 'dist')
, publicPath: './dist/' //当使用代码分割时,publicPath很重要,它将告诉webpack从哪儿去加载其他打包的文件
, pathinfo : true
}
}
</code></pre>
<p>执行webpack打包之后,我们可以看到结果<br><img src="/img/bVJS9m?w=1352&h=528" alt="执行webpack打包" title="执行webpack打包"></p>
<p>我们发现,webpack打包生成了<code>bundle.js</code>以及<code>1.bundle.js</code>两个文件<br>查看文件的内容,我们可以发现</p>
<pre><code class="javascript">//bundle.js
/******/ (function(modules) { // webpackBootstrap
/******/ /*
webpack 集成的代码,这里略
*/
/******/ __webpack_require__.p = "./dist/"; //按需加载的路径
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/*!*********************!*\
!*** ./js/entry.js ***!
\*********************/
/***/ function(module, exports, __webpack_require__) {
__webpack_require__(/*! ./a */ 1)
__webpack_require__.e/* nsure */(1, function (require) {
__webpack_require__(/*! ./c */ 3)
console.log('done!')
})
/***/ },
/* 1 */
/*!*****************!*\
!*** ./js/a.js ***!
\*****************/
/***/ function(module, exports) {
console.log('I am a')
/***/ }
/******/ ]);</code></pre>
<pre><code class="javascript">//1.bundle.js
webpackJsonp([1],[
/* 0 */,
/* 1 */,
/* 2 */
/*!*****************!*\
!*** ./js/b.js ***!
\*****************/
/***/ function(module, exports) {
console.log('I am b')
/***/ },
/* 3 */
/*!*****************!*\
!*** ./js/c.js ***!
\*****************/
/***/ function(module, exports) {
console.log('I am c')
/***/ }
]);</code></pre>
<p><code>a.js</code>的内容被打包到bundle.js之中,而<code>b.js</code>,<code>c.js</code>则位于<code>1.bundle.js</code>中,<code>b.js</code>,<code>c.js</code>从主入口文件中分离了出来,而且只有<code>c.js</code>的内容被执行了</p>
浅谈javascript的原型及原型链
https://segmentfault.com/a/1190000008350004
2017-02-14T17:53:24+08:00
2017-02-14T17:53:24+08:00
Derycktse
https://segmentfault.com/u/derycktse
1
<p>原型与原型链是javascript里面最最核心的内容,如果不能理解它们之间的存在关系的话,那么我们是不能理解这门语言的。</p>
<p>在JS中,主要有两种创建对象的方法, 分别是对象字面量以及调用构造函数</p>
<pre><code class="javascript">//对象字面量
var obj1 = {}
//调用构造函数
var obj2 = new Object()</code></pre>
<p>其实上述两种创建对象的方法,本质上是一样的,都是JS引擎调用对象的构造函数来新建出一个对象。构造函数本身也是一个普通的JS函数</p>
<p>下面我们来看一个例子</p>
<pre><code class="javascript">//创建构造函数
function Person(name){
this.name = name
}
//每个构造函数JS引擎都会自动添加一个prototype属性,我们称之为原型,这是一个对象
//每个由构造函数创建的对象都会共享prototype上面的属性与方法
console.log(typeof Person.prototype) // 'object'
//我们为Person.prototype添加sayName方法
Person.prototype.sayName = function(){
console.log(this.name)
}
//创建实例
var person1 = new Person('Messi')
var person2 = new Person('Suarez')
person1.sayName() // 'Messi'
person2.sayName() // 'Suarez'
person1.sayName === person2.sayName //true</code></pre>
<p>我们借助上面的例子来理解构造函数-原型-实例,三者之间的关系,主要有几个基本概念</p>
<ul>
<li><p>构造函数默认会有一个<code>protoype</code>属性指向它的原型</p></li>
<li>
<p>构造函数的原型会有一个<code>consctructor</code>的属性指向构造函数本身, 即</p>
<pre><code class="javascript"> Person.prototype.constructor === Person</code></pre>
</li>
<li>
<p>每一个<code>new</code>出来的实例都有一个隐式的<code>__proto__</code>属性,指向它们的构造函数的原型,即</p>
<pre><code class="javascript">person1.__proto__ === Person.prototype
person1.__proto__.constructor === Person</code></pre>
</li>
</ul>
<p>了解了这些基本概念之后,我们再来看看javascript的一些原生构造函数的关系网,看下列的图</p>
<p><img src="/img/remote/1460000008350007" alt="javascript objects treasure map" title="javascript objects treasure map"><br>引自<a href="https://link.segmentfault.com/?enc=hVpUOAUUU6aTavsuNd%2BzoA%3D%3D.gjw96d6f1fdlmau2oJ220BwBwlWioaZGJG5ktVW6ELGo%2FFJqg%2Fcg7mWigrc4XrSLrMTdgsRwj9Ga%2BUfAxekr4PO4z%2FPGlVBmPve4UuZ31BqR4DO8Uq2gPhz%2FSYnHZGMk" rel="nofollow">stackoverflow</a></p>
<p>按照我们上面的理解, Oject本身是一个构造函数,它也是一个对象,那么</p>
<pre><code class="javascript"> Object.__proto__ === Function.prototype</code></pre>
<p>为了方便我们记住上图,还有几个需要我们知道的特殊概念:</p>
<ul>
<li>
<p><code>Function</code>的原型属性与<code>Function</code>的原型指向同一个对象. 即</p>
<pre><code class="javascript"> Function.__proto__ == Function.prototype</code></pre>
</li>
<li><p><code>Object.prototype.__proto__ === null</code></p></li>
<li><p><code>typeof Function.prototype === 'function'</code></p></li>
</ul>
使用vue-loader
https://segmentfault.com/a/1190000008328025
2017-02-12T21:36:39+08:00
2017-02-12T21:36:39+08:00
Derycktse
https://segmentfault.com/u/derycktse
1
<h2>介绍</h2>
<p><a href="https://link.segmentfault.com/?enc=CXMGiTYBlXU8ynbUKxqjPw%3D%3D.D4mGD9vXM8XVuGdkzvNA4dDJ8FicvoXr8QThismhz0%2Btged5R%2BIeI3i2TyFBbB%2Fv" rel="nofollow">vue-loader</a>是一个可以将Vue组件转换成javascript模块的webpack loader</p>
<h2>构成</h2>
<p>vue组件的文件一般都是使用<code>*.vue</code>,这样的形式作为文件名。*.vue文件包含了三个关键语言块:<code><template>, <script>, <style></code></p>
<p>需要注意的是每一个<code>*.vue</code>文件最多只能有一个<code><template></code></p>