2017年2月8日 星期三

Step By Step : Vue.js 2 + TypeScript

如何使用 TypeScript 撰寫 Vue.js 2

  1. 建立專案資料夾 lab01,並初始化套件管理定義檔 package.json.
    npm init -y:表示定義檔內容採用預設值.
    D:\vue_lab>mkdir lab01
    D:\vue_lab>cd lab01
    D:\vue_lab\lab01>npm init -y
    Wrote to D:\vue_lab\lab01\package.json:

    {
      "name": "lab01",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "keywords": [],
      "author": "",
      "license": "ISC"
    }
  2. 開始安裝套件
    相依套件:
    D:\vue_lab\lab01>npm install vue --save      (v2.1.0) 安裝 vuejs
    D:\vue_lab\lab01>npm install vue-class-component --save   (4.4.0)ES/TypeScript decorator 用以類別的方式撰寫 component
    開發時期相依套件:
    D:\vue_lab\lab01>npm install typescript --save-dev  (v2.1.5)安裝 typescript。將 ts 編譯為 js 檔
    D:\vue_lab\lab01>npm install webpack --save-dev   (v2.2.1)安裝 webpack module loader。將 js 檔打包
    D:\vue_lab\lab01>npm install webpack-dev-server --save-dev  (v2.3.0)安裝 webpack 開發伺服器
    D:\vue_lab\lab01>npm install concurrently --save-dev  (v3.1.0)安裝concurrently。可同時執行多個命令
  3. 設定 package.json 檔案中 script 區段,最後文件如下
    {
      "name": "lab01",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "build": "tsc -w",
        "server": "webpack-dev-server --open --inline --hot",
        "start": "concurrently \"npm run build\" \"npm run server\""
      },
      "keywords": [],
      "author": "",
      "license": "ISC",
      "dependencies": {
        "vue": "^2.1.10",
        "vue-class-component": "^4.4.0"
      },
      "devDependencies": {
        "concurrently": "^3.1.0",
        "typescript": "^2.1.5",
        "webpack": "^2.2.1",
        "webpack-dev-server": "^2.3.0"
      }
    }

    tsc -w :監視ts檔案,當發生變更立即編譯
    webpack-dev-server --open --inline --hot : 啟動 dev server,選項可查文件
  4. 在根目錄下新增 tsconfig.json
    {
      "compilerOptions": {
        "target": "es5",
        "module": "commonjs",
        "moduleResolution": "node",
        "sourceMap": true,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "lib": [ "es2015", "dom", "es2015.promise" ],
        "noImplicitAny": true,
        "suppressImplicitAnyIndexErrors": true
      }
    }
  5. 在根目錄下新增 webpack.config.js
    module.exports = {
        entry: './app.js',
        output: {
            publicPath: '/',
            filename: 'app.bundle.js'
        },
        resolve: {
            alias: {
                'vue$': 'vue/dist/vue.common.js'
            }
        },
    }

    將 app.js 打包成 app.bundle.js
  6. 在根目錄下新增 app.ts
    import Vue = require('vue');
    import Component from 'vue-class-component'

    @Component
    class App extends Vue{
        //data
        name = "max";
        counter = 0;

        //computed
        get message(){
            return `${this.name} - ${this.counter}`;
        }

        //methods
        add(){
            this.counter++;
        }
    }

    var app = new App({ el: "#app"});
  7. 在根目錄下新增 index.html
    <html>
        <body>
            <div id="app">
                {{message}}
                <button type="" @click="add">add</button>
            </div>
            <script src="./app.bundle.js"></script>
        </body>
    </html>
  8. 執行 stat 命令,啟動 tsc 監視與啟動 webpack dev server ,並在 browser 中查看結果運作是否正常
    D:\vue_lab\lab01> npm start



資源:

2016年4月20日 星期三

將 TypeScript 檔案編譯至特定的位置

 ASP.NET Core 樣版的預設目錄結構如下
  • wwwroot:是用來存放與網站有關的靜態檔案
所以 TypeScript(*.ts) 的檔案就不應該放在 wwwroot 下面.

假設我正在寫一個 ng 的專案,我在專案 root 下建立一個名為 ngApp 的資料夾,用來存放 TypeScript 檔案,這個資料夾有自己的目錄結構,我希望編譯出來的 js 檔案可以放在 wwwroot/scripts 下面,該如何做呢?

圖片說明

1.希望編譯出的 ts 放在 wwwroot/script 下
2.開發 ng app 的 TypeScript 檔



可以在專案目錄下建立一個  tsconfig.json 檔案,compiler 會根據裡面的定義來處理,檔案內容如下
{
  "compilerOptions": {
    "noImplicitAny": false,
    "noEmitOnError": true,
    "removeComments": false,
    "sourceMap": true,
    "target": "es5",
    "rootDir": "",
    "outDir": "./wwwroot/scripts"
  },
    "exclude": [
        "node_modules",
        "wwwroot"
    ]
}


必需在 compilerOptions 屬性下設定 rootDir,outDir 這2個屬性
  • rootDir: 告訴 compiler 要編譯的 ts 檔案的根目錄在哪.
                   通常就是專案下所有的 ts檔,所以設定空白.
  • outDir:  告訴 compiler 編譯後產生的 js 檔要放在哪.
                   這邊指定在 wwwroot/scripts 目錄下
這邊要注意的是,如果只設定 outDir 而沒有設定 rootDir,則整個專案下的 ts 檔所編譯出來的 js 都會放在 wwwroot/scripts 下面,所以你想要output出來的目錄結構跟開發是相同的,必需設 定 rootDir 屬性才行.






2016年4月17日 星期日

使用 Visual Studio Code 開發 .NET Core RC2 版的程式

ASP.NET Core 1.0 RC2 將不使用 DNX 運作,將全面改以 .NET Core CLI 的方式運作,但目前 .NET Core RC2 尚未 release,VS 2015 update 2 還是使用 DNX 方式在編譯和執行程式.

參考 :http://www.hanselman.com/blog/AnUpdateOnASPNETCore10RC2.aspx

在 ASP.NET Community Standup - April 12th, 2016 - The Quickening 會議裡面有 demo 如何使用 Visual Studio Code - Insiders 來開發 .NET Core RC2,它可支援 Intellisence,debug,等等


  1. 下載 VS Code - Insiders 版本(這可以算是內部預覽版本)
    https://code.visualstudio.com/Download#insiders
  2. 下載 omnisharp-vscode extension:讓 VS Code - Insiders 支援 .NET Core RC2 開發環境
    https://github.com/OmniSharp/omnisharp-vscode/releases
  3. 安裝 omnisharp-vscode extension
    啟動 VS Code - Insiders,在工具列 檔案→開啟檔案(Ctrl + O),選擇第二步下載的 extension,按開啟。

    安裝完成後會要求重新啟動 VS Code - Insiders
  4. 如果要讓 VS Code - Insiders 可以 deubg application,需要做設定
    https://github.com/OmniSharp/omnisharp-vscode/wiki/Portable-PDBs#downloading-a-net-cli-which-supports-debugtype-option
  5. 接著就可以在 VS Code - Insiders 上開發  .NET Core RC2 的程式了,關於如何寫可參考

    使用 .Net Core CLI 建立 Console Application

    ASP.NET Core 如何使用 .Net full framework 與 .Net core

2016年4月11日 星期一

使用 .Net Core CLI 建立 Console Application

  1. 安裝 .Net Core SDK & CLI (撰文時最新版本為:1.0.0-rc2-002345)

    從 GitHub 下載:https://github.com/dotnet/cli,根據 OS 選擇想下載的安裝檔。
    .Net Core SDK installer 包含 .Net Core + CLI tools
    在這選擇 Widnwos x64 下載及安裝
  2. 安裝完成後,開啟 cmd 視窗執行以下命令檢查安裝是否正確
     
        dotnet --info
    



    想知道 dotnet 命令支援哪些參數,可以使用 -h or --help 查看
  3. 建立專案目錄並進到目錄下
        D:\lab>mkdir app1
        D:\lab>cd app1
        D:\lab\app1>
    
  4. 建立 console application 專案
        dotnet new
    

    執行命令後會產生2個檔案
    Programe.cs:主程式
    project.json:專案的組態檔
  5. 在專案目錄下,新增 NuGet.config.
    為了取得最新版的程式,否則在之後的第7步會發生找不到相關的.Net Core套件的錯誤
    記得在 config 檔第一行加上
    <?xml version="1.0" encoding="utf-8"?>
    
      
        
        
      
    
    
  6. 修改組態檔內容.
    因為還沒有正式版的 rc2 還沒 release,後面所指定的版本號可能會在剛剛上一步設定的 packagesources(AspNetVNext) 找不到,因此改成1.0.0-*,表示要從 nuget 中取得最新版的.Net Core套件



    修改上圖紅色框的版本號如下
        
    {
      "version": "1.0.0-*",
      "compilationOptions": {
        "emitEntryPoint": true
      },
      "dependencies": {
        "Microsoft.NETCore.App": {
          "type": "platform",
          "version": "1.0.0-*"
        }
      },
      "frameworks": {
        "netcoreapp1.0": {}
      }
    }
    
  7. 執行套件還原.
    執行完成後 cli 會根據 project.json 的內容自動產生 project.lock.json 檔,這檔案是由 cli 來維護.
    可參考:http://blog.falafel.com/what-is-project-lock-json/
        
    dotnet restore
  8. 接著執行 dotnet run,他會建置並執行程式



    .NET Core 內含 CoreRT,可以將程式編譯成 native(機器語言),這樣就不需要依靠 corefx/runtime 即可執行程式,不過這個版本似乎有點問題,沒有成功產生



    找到有人發了issue,但還沒至何回覆
    https://github.com/dotnet/cli/issues/2299


2015年10月5日 星期一

Windows 10 - 如何在目前資料夾中使用快捷鍵開始命令提示字元(cmd)



三種方式
1. Shift + F10, W, 按 Enter

2. Alt + D, 輸入 cmd 按 Enter

3. F10, F, P

具有 Administrator 身份的 cmd
F10, F, M, A

2014年6月1日 星期日

[ASP.NET Identity 2.0]如何將 ASP.NET Identity 的資料表 PK 欄位的資料型別由 NVARCAHR(128) 改為 INT

ASP.NET Identity 2.0 所提供的資料表中 PK 欄位資料型別皆為 nvarchar(128) ,所儲存的值為 GUID 格式字串。
如果我們想將 PK 的資料型別改為 int 該如何作呢?
以下將一步步實現這個過程。

請建立一個 ASP.NET MVC 5 專案,驗證方式請選擇「個別使用者帳戶」。


  1. 打開並修改 Models\IdentityModels.cs 為以下程式碼
     
    namespace WebApplication1.Models
    {
        // 您可以在 ApplicationUser 類別新增更多屬性,為使用者新增設定檔資料,請造訪 http://go.microsoft.com/fwlink/?LinkID=317594 以深入了解。
        public class ApplicationUser : IdentityUser<int, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>
        {
            public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser, int> manager)
            {
                // 注意 authenticationType 必須符合 CookieAuthenticationOptions.AuthenticationType 中定義的項目
                var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
                // 在這裡新增自訂使用者宣告
                return userIdentity;
            }
        }
        public class ApplicationUserRole : IdentityUserRole<int>
        {
        }
    
        public class ApplicationUserLogin : IdentityUserLogin<int>
        {
        }
    
        public class ApplicationUserClaim : IdentityUserClaim<int>
        {
        }
    
        public class ApplicationRole : IdentityRole<int, ApplicationUserRole>
        {
        }
    
        public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, int, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>
        {
            public ApplicationDbContext()
                : base("DefaultConnection")
            {
            }
    
            public static ApplicationDbContext Create()
            {
                return new ApplicationDbContext();
            }
        }
    }
    
    
  2. 打開並修改 App_Start\IdentityConfig.cs 的 ApplicationUserManager 類別
     
        public class ApplicationUserManager : UserManager<ApplicationUser, int>
        {
            public ApplicationUserManager(IUserStore<ApplicationUser, int> store)
                : base(store)
            {
            }
    
            public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
            {
                var manager = new ApplicationUserManager(new UserStore<ApplicationUser, ApplicationRole, int, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>(context.Get<ApplicationDbContext>()));
                // 設定使用者名稱的驗證邏輯
                manager.UserValidator = new UserValidator<ApplicationUser, int>(manager)
                {
                    AllowOnlyAlphanumericUserNames = false,
                    RequireUniqueEmail = true
                };
                // 設定密碼的驗證邏輯
                manager.PasswordValidator = new PasswordValidator
                {
                    RequiredLength = 6,
                    RequireNonLetterOrDigit = true,
                    RequireDigit = true,
                    RequireLowercase = true,
                    RequireUppercase = true,
                };
                // 註冊雙因素驗證提供者。此應用程式使用手機和電子郵件接收驗證碼以驗證使用者
                // 您可以在這裡寫下自己的提供者和外掛程式。
                manager.RegisterTwoFactorProvider("PhoneCode", new PhoneNumberTokenProvider<ApplicationUser, int>
                {
                    MessageFormat = "Your security code is: {0}"
                });
                manager.RegisterTwoFactorProvider("EmailCode", new EmailTokenProvider<ApplicationUser, int>
                {
                    Subject = "安全碼",
                    BodyFormat = "Your security code is: {0}"
                });
                manager.EmailService = new EmailService();
                manager.SmsService = new SmsService();
                var dataProtectionProvider = options.DataProtectionProvider;
                if (dataProtectionProvider != null)
                {
                    manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser, int>(dataProtectionProvider.Create("ASP.NET Identity"));
                }
                return manager;
            }
        }
    
到這邊大部份重要的類別都改完了,這時建置一下專案後發現還有一些錯誤,讓我們接著來處理

調整 User.Identity.GetUserId() 擴充方法
在 AccountController.cs 中大量使用了 GetUserId() 擴充方法,他是用來從 Identity 中擷取 UserId。














會發生錯誤是因為我們現在的 UserId 定義為 int,而這個擴充方法會回傳 string,因此我們需要自建一個擴充方式來處理這個問題。
建立完成後我們將所有使用到的 GetUserId() 方法,改為 GetUserId<int>()。
記得有使用到自建的擴充方法檔案中要 using WebApplication1.ExtensionMethods 命名空間
 
using System.Security.Principal;
using Microsoft.AspNet.Identity;
namespace WebApplication1.ExtensionMethods
{
    public static class IdentityExtensions
    {
        public static T GetUserId<T>(this IIdentity identity) where T : IConvertible
        {
            return (T)Convert.ChangeType(identity.GetUserId(), typeof(T));
        }
    }
}

再來將 ConfirmEmail 方法的 userId 參數,資料型別由 string 改為 int。

最後我們 Startup 中的 app.UseCookieAuthentication…程式碼換掉
 
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath = new PathString("/Account/Login"),
                Provider = new CookieAuthenticationProvider
                {
                    OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser, int>(TimeSpan.FromMinutes(30),
                    regenerateIdentityCallback: (manager, user) => user.GenerateUserIdentityAsync(manager),
                    getUserIdCallback: (identity) => identity.GetUserId<int>())
                }
            });


這樣我們就完成了 Table PK 由 nvarchar(128) 改為 int。




參考資料:
http://stackoverflow.com/questions/22547712/asp-net-identity-change-guid-to-int
https://aspnetidentity.codeplex.com/workitem/2186

2013年10月5日 星期六

使用 SyntaxHighlighter 為 Blogger 加入程式碼區塊

查了一下關於為 Blogger 加入程式碼區塊的功能,其實有滿多套件與做法可用,最後決定用 SyntaxHighlighter 來處理這個問題。
  1. 進入網誌,範本→編輯 HTML
  2. 在 </head> 前面加入以下的程式碼後儲存範本
     
    
    
    
    
    
接可以在撰寫文章時切到 HTML ,使用 pre tag 包住程式碼
 
 
    function abc(){
        alert('abc');
    }

SyntaxHighlighter 支援許多語言高亮顯示,可參考以下連結
http://alexgorbatchev.com/SyntaxHighlighter/manual/brushes/