cygwin

windows 下安装 cygwin 环境。 下载 setup-x86_64.exe,通常应从 mirror 安装软件包,否则可能很慢。 GUI 下不方便查找选择 mirror,而且可能没有要使用的 mirror,可直接用命令行指定 mirror。

setup-x86_64.exe --local-package-dir D:\software\ --root D:\cygwin64\ -O -s http://mirrors.ustc.edu.cn/cygwin/
  • --help 查看命令行帮助。
  • 默认会下载软件包并安装,--download 只下载,-L--local-install 直接从本地目录安装。
  • --local-package-dir D:\software\ 本地软件包目录。--root cygwin 安装根目录,安装程序会自动创建此目录。
  • -O -s http://xxx/cygwin/ 直接从指定 site (mirror) 安装。

其他可能有用的选项:

  • --no-admin 普通用户安装,不要求 admin 权限。--no-shortcuts 不创建快捷方式。
  • -g--upgrade-also 升级已有软件包,--packages 指定要安装的软件包。
  • -q 安静模式(自动安装)。

cygwin 下可使用如下命令自动安装软件包:

setup-x86_64.exe --local-package-dir 'D:\software\' --root 'D:\cygwin64\' -O -s http://mirrors.ustc.edu.cn/cygwin/ --no-shortcuts --no-admin --packages ping,vim -q

cygwin 默认将 windows 分区盘符挂载在 /cygdrive/ 下,第一次启动 cygwin shell 环境前可修改配置,命令如下:

D:\cygwin64\bin\sed -re "s/(^[^#].*?\s\/)cygdrive(\b\s+\w+\s+)(.*)$/#\0\n\1\2\3\nD:\/home \/home auto \3/" /etc/fstab -i~
D:\cygwin64\bin\bash --norc -c "x=$(/bin/readlink -m /etc/hosts) && /bin/ln -sf ${x#/cygdrive} -T /etc/hosts"
  • 设置 windows 分区直接挂载在根目录(/)下,使用 D:/home 作为 /home 目录。
  • 修正 hosts 软链接(?)。

还可以直接使用 vi 编辑:

D:\cygwin64\bin\vi -u NONE /etc/fstab

第一次启动登录 shell(如 mintty -) 时将自动创建用户 home 目录。

git 配置

  • 默认用户(全局)配置文件 ~/.gitconfig
  • 全局 ignore 文件可通过全局 core.excludesFile 配置,其能够识别 ~ home 路径。
git config --global core.excludesFile "~/.config/gitignore"
#echo ".envrc .local/" | tr " " "\n" >> ~/.config/gitignore

科学上网

Scala 构建工具 sbt

  • 时间: 2019-01

sbt 支持多种方式安装,参考 sbt download 。 可直接使用 sdkman 安装:

sdk install sbt 1.2.8

sbt 使用 sbt-lancher 启动,其可在启动 sbt 前单独配置,参考 sbt Launcher Configuration 。 启动逻辑参考安装目录下的 bin/sbt-launch-lib.bash 脚本,sbt 默认支持使用本地文件完成启动。

sbt 默认会将安装目录下的 lib/local-preloaded/ 文件夹同步到 ${sbt.preloaded} 目录(默认为 ~/.sbt/preloaded/)下。 同时查看默认的启动器配置,会尝试使用 ${sbt.preloaded} 作为仓库。 注意如果配置了 [ivy] 下的 repository-config 配置文件存在,则会覆盖 [repositories] 配置。

$ 7z e ~/.sdkman/candidates/sbt/1.2.8/bin/sbt-launch.jar -so sbt/sbt.boot.properties
# ... ...
[repositories]
  local
  local-preloaded-ivy: file:///${sbt.preloaded-${sbt.global.base-${user.home}/.sbt}/preloaded/}, [organization]/[module]/[revision]/[type]s/[artifact](-[classifier]).[ext]
  local-preloaded: file:///${sbt.preloaded-${sbt.global.base-${user.home}/.sbt}/preloaded/}
  maven-central
# ... ...

[ivy]
  ivy-home: ${sbt.ivy.home-${user.home}/.ivy2/}
  checksums: ${sbt.checksums-sha1,md5}
  override-build-repos: ${sbt.override.build.repos-false}
  repository-config: ${sbt.repository.config-${sbt.global.base-${user.home}/.sbt}/repositories}

sbt 脚本加 -v 参考可查看最终启动参数,可看到默认启动参数如下:

$ sbt -v
[process_args] java_version = '8'
# Executing command line:
java
-Xms1024m
-Xmx1024m
-XX:ReservedCodeCacheSize=128m
-XX:MaxMetaspaceSize=256m
-jar
/home/observer.hany/.sdkman/candidates/sbt/current/bin/sbt-launch.jar

为避免 sbt 从官方仓库下载东西过慢,可配置代理(镜像)仓库加速下载, 参考 sbt Configuration。 同时参考 sbt-lancher 默认配置,可添加 ${sbt.preloaded} 加速下载, 可配置 ~/.sbt/repositories 文件(该文件同时会覆盖 sbt-lancher 的 repositories 配置)内容如下(使用 aliyun maven 仓库):

[repositories]
  local
  maven-local
  local-preloaded-ivy: file:///${sbt.preloaded-${sbt.global.base-${user.home}/.sbt}/preloaded/}, [organization]/[module]/[revision]/[type]s/[artifact](-[classifier]).[ext]
  local-preloaded: file:///${sbt.preloaded-${sbt.global.base-${user.home}/.sbt}/preloaded/}
  maven-aliyun: https://maven.aliyun.com/nexus/content/groups/public

另参考文档,可设置 sbt.override.build.repos 忽略项目显式配置的仓库。

sbt 同时使用了 maven 仓库和 ivy 仓库(?),参考 Proxying Ivy Repositories, 两者需要分别使用不同的代理(不配置 ivy 仓库会怎样?)。 文档图示上有两个 ivy 仓库:

sbt 启动时将从仓库下载相关文件。 经测试发现 maven 本地仓库文件不完整可能下载失败报错,删除不完整的库目录即可。

idea

  • 环境:ubuntu-mate 16.04
  • 版本:2018.3
  • 时间:2019-01

安装

idea 下载页面 下载 idea 社区版, 可下载不带 jdk 的版本,减少下载大小同时使用自定义统一的 jdk 版本。

curl -sSL -O https://download-cf.jetbrains.com/idea/ideaIC-2018.3.4-no-jdk.tar.gz

解压后参考 Install-Linux-tar.txt 文档和 bin/idea.sh 脚本,默认用户配置目录为 $HOME/.IdeaIC2018.3/ 。 修改解压后的目录为同名目录(但不包含前缀 '.')。

tar xf ~/software/idea/ideaIC-2018.3.4-no-jdk.tar.gz
mv idea-IC-183.5429.30/ -T IdeaIC2018.3
cd IdeaIC2018.3

Linux 下 java 原生 GUI 字体显示有问题,jetbrains 自带的 jdk 做了优化,字体显示效果好很多。 不带 jdk 的版本,可下载安装 jetbrains 定制的 jdk。 可 使用插件安装, 或者手动下载安装。

curl -L -O https://dl.bintray.com/jetbrains/intellij-jdk/jbsdk8u202b1483.4_linux_x64.tar.gz
mkdir ~/opt/jdk-jbsdk8u202b1483.4
cd ~/opt/jdk-jbsdk8u202b1483.4
tar xf ~/software/jdk/jbsdk8u202b1483.4_linux_x64.tar.gz
sdk install java jbsdk8 $PWD

参考 bin/idea.sh 脚本,可设置 $HOME/.IdeaIC2018.3/config/idea.jdk 指定 jdk 路径。

mkdir ~/.IdeaIC2018.3/config/ -p
readlink -f ~/.sdkman/candidates/java/jbsdk8 > ~/.IdeaIC2018.3/config/idea.jdk

每个 JDK 版本的字体相关配置在 ~/.java/fonts/<jdk版本>/ 下(?)。

配置

  • 首次执行 bin/idea.sh 脚本启动,启动后 "Configure" 菜单点击 "Create Desktop Entry" 创建桌面启动项。 关闭后重新启动,dock 栏自动关联上创建的启动项,可选择固定图标到 dock 栏。

  • "View" 菜单,勾选 "Toolbar",显示工具栏。

打开 "Settings" 窗口,进行以下配置:

  • "Appearance & Behavior"

    • "Appearance" 默认字体部分中文不能显示,可勾选 "Use custom font" 设置自定义字体。

    "Noto Sans CJK SC Regular" 字体可显示中文,但界面中加粗字体显示效果较差。 "Ubuntu" 字体整体感觉较好,但仍存在部分中文不能显示的问题。 综合倾向于使用 "Ubuntu" 字体,大小 16;或保持 IDE 默认字体。 IDE 仅个别地方出现中文,且启动时设置 LANG=en_US.UTF-8 可避免使用中文(是否有其他副作用?)。

    • "System Settings"
      • 取消勾选 "Reopen last project on startup" 。
      • "Project Opening", "Default directory" 设置为 ~/workspace/(转为实际路径) 。
      • "System Settings" -> "Updates", 取消勾选 "Automatically check updates" 。
  • "Editor" -> "Font" 。idea 默认字体 "DejaVu Sans Mono",大小修改为 15 。"Fallback font" 设置为 "Noto Sans Mono CJK SC Regular" 。

    idea 默认字体 "DejaVu Sans Mono",大小 12(idea 字体显式偏小,可修改为 14 或 15),"Line spacing" 1.0 ,显示效果不错。 ubuntu 默认编辑器字体 "Ubuntu Mono",大小 13,在系统编辑器(pluma)显示效果不错, 但在 idea 中效果稍差(该字体显示较小,可考虑大小设置为 17)。 "DejaVu Sans Mono" 显示中文效果不好(不包含中文字体?), 可尝试修改使用 字体 "Noto Sans Mono CJK SC Regular"(需要安装 fonts-noto-cjk 软件包), 大小 13, "Line spacing" 0.85 , 字体和行距调整可对比参考系统编辑器的效果。 但英文感觉 "DejaVu Sans Mono" 字体显示更清爽。 字体使用 "DejaVu Sans Mono" 时,可设置 "Fallback font" 为 "Noto Sans Mono CJK SC Regular",此时中英文的显示效果都不错。

  • "Keymap" 选择 "Eclipse"。修改快捷键,原快捷键可先删除再重新添加到后面(?)。 配置参考配置目录下 config/options/keymap.xmlconfig/keymaps/Eclipse\ copy.xml

    • "Main menu" -> "Edit"
      • "Copy Paths" 修改为 "Ctrl+Alt+Shift+C", "Copy Reference" 修改为 "Ctrl+Shift+C"。即两者交换,后者更常用。 这组快捷键同时影响 project 树上的 "Copy Path" 和 "Copy Relative Path"。
    • "Main menu" -> "Code" -> "Completion"
      • "Basic", 默认 "Ctrl+空格", 修改为 "Alt+/", 追加原快捷键 "Ctrl+空格" 。 " "SmartType", 默认 "Alt+Shift+空格", 修改为 "Alt+.", 追加原快捷键 "Alt+Shift+空格" 。
      • "Cyclic Expand Word",默认 "Alt+/",修改为 "Alt+N" 。这功能貌似用处不大(?)。
  • "Plugins" 安装 "Scala" 插件。

clion

CLion 2018.3.2 重置 30 天试用:

# ~/.CLion2018.3 目录下操作
rm config/eval/ -rf
sed -re '/<property name="evlspr/ d' config/options/options.xml -i
rm -rf ~/.java/.userPrefs/jetbrains/clion/

~/.java/.userPrefs/prefs.xml 下还保存了 JetBrains.UserIdOnMachine(貌似不影响重置?)。

可修改启动脚本(如 clion.sh)在启动 IDE 前自动检查试用。如添加如下一行代码:

idea-clean.sh "${HOME}"/.CLion2018.3

设置 cmake:

sudo dpkg-divert --rename --add /usr/bin/cmake
sudo update-alternatives --install /usr/bin/cmake cmake ${HOME}/opt/clion-2018.3.2/bin/cmake/linux/bin/cmake 60

使用 cmake 编译 nasm, 参考: https://metricpanda.com/using-nasm-with-cmake-and-clang .

enable_language(ASM_NASM)

WebStorm (2018.1.5) 配置

  • "Languages & Frameworks"

    • "Node.js and NPM" 选择 "Node interpreter" 版本。
  • "Editor" -> "CodeStyle"

    • "JavaScript" (TypeScript 同样设置)
      • "Spaces"
        • "Within", 勾选 ("Brackets"?), "Object literal braces", "ES6 import/export braces" 。
      • "Punctuation", Use "double" quotes "always" (?) 。
    • "HTML"
      • "Other", wrap 取消勾选 "Align attributes" (?) 。

eclipse java 开发环境

  • 环境:ubuntu-mate 16.04
  • 版本:oxygen (4.7.x)
  • 时间:2017-12

建议使用 oxygen (4.7.x), 更新版本 2018-09 (4.9.x)/gtk3 发现如下问题:

  1. gtk2 java 编辑器左右拖动滚动条时花屏(gtk3 貌似没问题)。
  2. 字体对话框的字体预览未渲染出文字。
  3. java 编辑器时常出现文字颜色不对。
  4. 部分图标和控件不平滑,一些界面颜色不舒适。运行进程停止后,停止按钮和相关调试按钮没有变灰(但也不可点击)。
  5. 调试功能有时会不好用(?):点击调用栈没有定位到代码(?),代码面包屑导航未完整显示(?)。
  6. 应用市场有时会报错。
  1. 下载软件包,可从国内镜像下载,如 USTC eclipse 镜像。 java 开发可下载 java 版,其他插件按需安装。

  2. 解压下载的软件包,解压后默认文件夹名为 eclipse,建议修改为对应开发环境和版本名,如 eclipse-java-oxygen-3a,同时设置一个对应开发环境的软链接。

    tar xf ~/software/eclipse/eclipse-java-oxygen-3a-linux-gtk-x86_64.tar.gz
    mv eclipse eclipse-java-oxygen-3a -T
    ln -s eclipse-java-oxygen-3a/ eclipse-java -Tf

    为跟踪配置修改历史,可将相关配置文件添加到 git 管理:

    cd eclipse-java/
    git init .
    echo $'*\n!.gitignore\n!eclipse.ini' > .gitignore
    git add .
    git add plugins/org.eclipse.epp.package.java_*/plugin.xml -f
    git commit -m 'init'
  3. 设置 jvm 参数。编辑 eclipse.ini,在 -vmargs 前添加 -vm 设置 jdk bin 路径,如:

    -vm
    /usr/lib/jvm/java-8-openjdk-amd64/bin/

    按需修改 -Xms, -Xmx 等参数,建议修改为 1024m 。 其他配置参考 eclipse 运行时参数帮助文档

    操作命令:

    ( vm=$'-vm\\\n'"$(readlink -f "${JAVA_HOME}")/bin/" && sed -e '/^-vmargs$/ i '"${vm}" -e '/^-vm$/,+1 d' eclipse.ini -i )
    sed -r -e 's#^(-Xms|-Xmx)[0-9].*$#\11024m#g' eclipse.ini -i
    mvn dependency:get -Dartifact=org.projectlombok:lombok:1.18.6
    sed -r -e "\$ a -javaagent:$HOME/.m2/repository/org/projectlombok/lombok/1.18.6/lombok-1.18.6.jar" -e "/^-javaagent.*\/lombok\/.*\.jar/ d" eclipse.ini -i
    
    git commit -am 'eclipse.ini set vm, lombok'
    
    # eclipse 4.7 使用 gtk2 更稳定友好?
    sed -r -e $'/^--launcher.appendVmargs/ i --launcher.GTK_version\\\n2' -e '/^--launcher.GTK_version/,+1 d' eclipse.ini -i
    git commit -am 'eclipse.ini use gtk2'
  4. 设置 dock 图标关联。建议每个开发环境 eclipse 关联一个 dock 图标。 linux dock 软件 (如 mate-desktop 自带的 dock applet) 通常使用 StartupWMClass 关联应用程序和 dock 图标。 eclipse 启动后默认使用 plugins/org.eclipse.epp.package.*/plugin.xml 插件配置的 appName property 设置主窗口 nameclass。 默认为 "Eclipse",建议修改为对应开发环境名,如 "eclipse-java" 。 这个配置应在第一次启动前修改,或修改后第一次启动 eclipse 时添加 -clean 参数清空配置缓存使修改生效。

    ( epp=java && sed -re '/\bname="appName"/,+1 s#\b(value=").*?(")#\1eclipse-'"${epp}"'\2#g' plugins/org.eclipse.epp.package.${epp}_*/plugin.xml -i )
    git commit -am 'set java appName'

    编写一个简单 Desktop 文件 ~/.local/share/applications/eclipse-java.desktop 内容如下:

    [Desktop Entry]
    Version=1.0
    Encoding=UTF-8
    Name=eclipse-java
    Type=Application
    Terminal=false
    Exec=sh -c "exec \$HOME/opt/eclipse-java/eclipse"
    Icon=/home/hanyong/opt/eclipse-java/icon.xpm
    Categories=Development;IDE;
    StartupNotify=true
    Keywords=Run;
    StartupWMClass=eclipse-java

    将此 desktop 文件添加为 dock 图标即可。

  5. eclipse workspace 相关的配置保存在 .metadata 目录下。 一个 workspace 目录只能被一个 eclipse 使用,切换 eclipse 版本时可备份恢复 .metadata 文件夹。

  6. 其他设置。

    • 关掉 always show welcome 。
    • Fonts 设置基本字体为 Monospace 11,或 DejaVu Sans Mono 11 。
    • 关掉 "Automatic Updates", News 关掉自动拉取 RSS , "Error Reporting" "Send mode" 设置为 "Never send reports"。
    • Web Browser 设置使用外部浏览器。
    • Maven 设置。
      • 取消勾选 "Download Artifact Sources" 。
      • 勾选 "Hide folders of physically nested modules (experimental)" 。
      • "User Interface" 勾选 "Open XML page in the POM editor by default" 。
    • "Java"/"Build Path", "Output folder name" 从 "bin" (eclipse 默认) 修改为 "target/classes" (maven 默认)。
    • Marketplace 安装 Spring Tools(需要优雅上网?),可只安装必须组件, Maven Support 和 spring boot support 。
  7. eclipse 应用市场搜索 fileExtension_<xxx> 可找到编辑对应扩展名文件的相关插件。

个人偏好设置:

  • 应用 Spring Tools 推荐的 M2E 配置(JDT 配置不需要)。
  • Java "Code Style", "Exception variable name in catch blocks" 设置为 "ex"(默认为 "e")。
  • Java "Code Style" Formatter 设置 "Eclipse [built-in-fixed]"。
    • "Indentation" 页勾选 "Indent" 勾选 "Empty lines" 。
    • "Line Wrapping" 页勾选上 "Never join already wrapped lines" 。
    • "Comments" 页取消 "Format line comments on first column" (4.8已默认), 勾选 "Never join lines",取消 "New line after @param tags"。 "Line width"/"Maximum width for comments" 设置为 120, 取消勾选 "Count width from comment's starting position"。
  • "Organize Imports" 设置 "Number of static imports needed for .*" 为 5。
  • Java -> Editor
    • 主节点
      • "Bracket highlighting" 选择 "Matching bracket and caret location"
    • "Content Assist" 页
      • 主页
        • Insertion 选择 "Completion overwrites" 。
        • 取消勾选 "Inert single proposals automatically" 。
        • 取消勾选 "Use static imports" 。
      • "Advanced", proposal kinds 列表取消勾选 "Jar Type Search"(非常慢?)。
    • "Save Actions", 勾选 "Perform the selected actions on save", 取消勾选 "Organize imports", 只勾选 "Additional actions", 点击 "Configure..." 。
      • "Code Organizing" 勾选 "Remove trailing whitespace", "Ingore empty lines" 。其他功能暂全部关闭(?)。 工具更好的自动处理空格,我们应该更关心代码本质(有意义的语法树)而不是文本。
  • "General" -> "Keys", 快捷键设置.
    • "Copy Qualified Name" 设置为 "Shift+Ctrl+C", When "In Windows", 对应的 "Toogle Comment" 取消快捷键设置以避免冲突。
    • "Save All" 设置为 "Ctrl+S"(与 idea 统一),对应的 "Save" 取消快捷键避免冲突。
    • "Quick Fix" 修改为 "Alt+Enter" (与 idea 统一?),对应的 "Properties" 取消快捷键避免冲突。
    • "Convert Local Variable to Field" 设置为 "Shift+Alt+F",对应的 "Force Return" 取消快捷键。

"Java" -> "Editor" -> "Templates" 添加模板

  • logger, Context "Java type members", 不自动插入。spring 插件已存在此同名模板,可直接修改其 Context (增强通用性)和模板内容。
${:import(org.slf4j.Logger,org.slf4j.LoggerFactory)}private static final Logger ${logger} = LoggerFactory.getLogger(${enclosing_type}.class);

eclipse scala 开发环境

  • 基于 eclipse java 开发环境安装 Scala IDE 插件。 可直接从应用市场安装。 可以只安装 "Scala IDE for Eclipse (required)" 核心组件。 "JDT Weaving for Scala" 是支持 eclipse 组件增强 JDT(参考 JDT Weaving ), 如果已经安装了其他 JDT Weaving 组件则不要安装(?)。

  • 如果要支持 maven(使用 scala-maven-plugin 插件)集成, 可安装 m2e-scala 插件(参考 Install m2eclipse-scala ), eclipse 应用市场无此插件(?),可通过 update site 安装。 eclipse java 版本已经自带 m2e 插件,只需在额外安装 m2e-scala 插件即可。

    maven 纯 scala 项目配置下源码目录和插件即可,参考 Usage, 混合 Java/Scala 代码参考 Mixed Java/Scala Projects 。 配置好后 eclipse 打开 maven 项目即可自动被识别配置为 Scala 项目。

    另参考 With M2Eclipse, 提供了一些混合 Java/Scala 代码的示例项目参考。

    已知缺点:eclipse scala 插件默认添加插件指定的 scala 依赖(scala-library 和 scala-reflect)到项目(而不是 maven 管理的 scala 依赖), 并且默认没有关联源码,因此查看 scala 源码会不方便。 FIXME: 是否可自定义添加带源码的 scala SDK 解决此问题?

  • sbt 是 scala 项目最重要的构建工具。 目前 eclipse 不能直接集成支持 sbt 管理构建的项目,可使用 sbteclipse 生成 eclipse 项目文件再导入 (类似旧 maven eclipse 插件的做法),每次 sbt 配置变更后,需要重新生成 eclipse 项目文件。 另外 scala 语言依赖还是会使用 scala 插件自带的 jar 包,一样存在不能查看源码的问题。 sbteclipse 插件有个 eclipseWithBundledScalaContainers 配置项, 但经测试没发现有什么用(?)。

eclipse c++ 开发环境

  • 基本配置与 eclipse java 开发环境类似。
  • 为方便跨平台及命令行编译,建议使用 cmake 管理编译,可安装 cmake4eclipse 插件集成管理项目构建,安装 CMake Editor 插件方便编写 cmake 配置。

cmake4eclipse 插件使用(参考插件文档 "CMake for CDT User Guide" / "Getting Started"):

  • 新建 eclipse 管理编译的 C++ 项目。默认有 "Debug","Relase" 两套设置,可删掉只保留一套,稍后再复制出来(?)。
  • 项目设置 "C/C++ Build" 节点,"Builder Settings" tab 勾选 "Generate Makefiles automatically"。通常默认已勾选。
  • "C/C++ Build" / "Tool Chain Editor" 节点,"Current builder" 选择 "CMake Builder (portable)"。默认可能为 "Gnu Make Builder"(?)。
  • "C/C++ General" / "Paths and Symbols" 节点,"Source Location" 设置源码根目录,默认为项目根目录。

cmake 使用参考:

C/C++ 依赖管理:

Visual Studio Code

  • 系统: ubuntu 18.04
  • 时间: 2019-02-09

参考:https://code.visualstudio.com/docs/setup/linux#_installation

安装:

curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg
sudo install -o root -g root -m 644 microsoft.gpg /etc/apt/trusted.gpg.d/
sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/vscode stable main" > /etc/apt/sources.list.d/vscode.list'

# ubuntu 18.04 不需要, https 已集成到 apt 核心
#sudo apt-get install apt-transport-https
sudo apt-get update
# 有两个版本, code 稳定, code-insiders 为内部版本, 建议安装 code.
sudo apt-get install code

打开配置, 左下角配置按钮菜单(或 "File" -> "Preferences")。

  • "Color Theme" 选择 "Default Light+",使用亮色(白底黑字)主题。配置项 "workbench.colorTheme": "Default Light+"
  • "Keyboard Shortcuts" 修改快捷键。
    • "Trigger Suggest" 快捷键修改为 "Alt+/" 。

安装插件:

  • 安装 "Eclipse Keymap" (alphabotsec.vscode-eclipse-keybindings) 插件,安装后默认就使用 eclipse 快捷键(?)。 参考: https://code.visualstudio.com/docs/getstarted/keybindings#_keymap-extensions

  • 安装 "modelines" "YAML" "Kubernetes" 等插件。

  • 插件市场可搜索支持指定文件扩展名的插件,如搜索 ext:java 可查找支持 .java 文件的插件。

打开 "Settings" 对 "User Settings" 进行相关配置。

  • "Application"
    • "Update"
      • 取消勾选 "Enable Windows Background Updates" (?)。
      • "Mode" 修改为 "manual", 不要自动更新(?)。
  • "Features" -> "Explorer", 取消勾选 "Auto Reveal", 当前活动的文件不要自动在左侧文件夹树同步展现。
  • 主菜单 "View" -> "Toggle Breadcrumbs"(或搜索 "bread", "Workbench" -> "Breadcrumbs", 勾选 "Breadcrumbs: Enabled"), 编辑器顶部显示面包屑路径导航。
  • 搜索 "key", "Application" -> "Keyboard", "Dispatch" 默认为 code, 但 X11 xkb 修改默认键盘布局后貌似有问题,可修改为 keyCode (?)。

  • "Text Editor"

    • "Minimap", 取消勾选 "Enabled" 。编辑器右侧显示缩图图,可能对快速导航有用(?),但占用了部分空间,暂不使用。
    • 搜索 "indent", "Insert Spaces" 取消勾选 "Insert spaces when pressing Tab" 。
    • "Files"
      • "Auto Save" 设置为 "afterDelay"(默认 "off"?),"Auto Save Delay" 设置为 60000 (默认 1000 ?)。
      • "Enable Trash" 取消勾选 使用操作系统回收站 。

参考系统自带编辑器 pluma 显示效果设置字体显示,修改如下。json 模式编辑删除自定义设置即可恢复默认设置。

  "editor.fontSize": 15,
  "editor.lineHeight": 24,
  "editor.fontFamily": "'DejaVu Sans Mono','Noto Sans Mono CJK SC Regular'",

markdown 扩展覆盖了全局的 workWrap 配置,打开了 wrap, 可以 JSON 配置方式打开配置,针对 markdown 添加如下配置关闭 wrap。 插入 "[markdown]" 后会自动补全 markdown 下相关配置(?)。

  "[markdown]": {
      "editor.wordWrap": "off",
      "editor.quickSuggestions": false
  }

参考: https://jmarcher.io/vs-code-markdown-and-word-wrap/

常用操作:

  • "View" -> "Command Palette", 搜索执行命令。如搜索 "reveal" 可找到执行在文件树展示当前文件的命令。

docker

  • 时间: 2018-03
  • 系统: ubuntu 16.04

配置 docker 软件包仓库:

# docker-engine
#sudo tee /etc/apt/sources.list.d/docker.list <<< "deb [arch=amd64] http://mirrors.aliyun.com/docker-engine/apt/repo/ ubuntu-$(lsb_release -cs) main"
#sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys F76221572C52609D
#curl -sS -L http://mirrors.aliyun.com/docker-engine/apt/gpg | sudo apt-key add -

# aliyun docker-ce
sudo tee /etc/apt/sources.list.d/docker.list <<< "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu/ $(lsb_release -cs) stable"
curl -sS -L http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -

# aliyun docker-ce VPC
#sudo tee /etc/apt/sources.list.d/docker.list <<< "deb [arch=amd64] http://mirrors.cloud.aliyuncs.com/docker-ce/linux/ubuntu/ $(lsb_release -cs) stable"
#curl -sS -L http://mirrors.cloud.aliyuncs.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -

安装 docker-ce:

sudo aptitude install docker-ce=17.03.2~ce-0~ubuntu-xenial -y
sudo aptitude hold docker-ce
sudo sed -r -e 's/^(#?\s*)(deb.*)$/#\2/' /etc/apt/sources.list.d/docker.list -i
  • 17.03.x 是当前 rancher 上 kubenetes 1.8 支持的 docker 版本(?) 。
  • 不自动升级 docker 。

清理被 docker 污染的 iptables 等相关网络设置:

for t in filter nat ; do sudo iptables -t $t -F ; sudo iptables -t $t -X DOCKER ; done
sudo iptables -t filter -X DOCKER-ISOLATION
#sudo rmmod iptable_filter iptable_nat
sudo ip link delete dev docker0

LXD 网络管理更友好,可使用 LXD 重新创建 docker NAT 网桥:

lxc network create docker1 ipv4.{address=192.168.254.1/24,dhcp=false,nat=true,routing=false,firewall=false} ipv6.address=none dns.domain=docker
  • docker 外部网桥名不能使用 docker0,否则 docker 会修改其地址,这是个 bug?

此时应设置 docker 服务依赖 lxd 服务(以设置 docker 网桥):

sudo sed -r -e '/^(After=|Requires=)/ s#$# lxd.service#' /etc/systemd/system/docker.service -i

或者 docker 创建网桥,但手动设置 NAT(避免 docker 污染):

sudo iptables -t nat -A POSTROUTING -s 192.168.254.0/24 ! -d 192.168.254.0/24 -j MASQUERADE

可编写 systemd 服务 iptables-nat.service

[Unit]
Description=Setup iptables NAT rule for localhost network
After=network.target

[Service]
Type=oneshot
Environment=LOCAL_NET=192.168.254.0/24
EnvironmentFile=-/etc/default/iptables-nat
ExecStart=/bin/bash -exc ' x="$${LOCAL_NET}" && x="$${x/-/\\/}" && iptables -t nat -A POSTROUTING -s $${x} ! -d $${x} -j MASQUERADE '
ExecStop=/bin/bash -exc ' x="$${LOCAL_NET}" && x="$${x/-/\\/}" && iptables -t nat -D POSTROUTING -s $${x} ! -d $${x} -j MASQUERADE '
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable iptables-nat.service
sudo systemctl start iptables-nat.service

设置 docker 服务启动参数:

  • graph docker 运行数据根目录,如 /home/repo/docker
  • bridge 使用指定网桥做 bridge 桥接网络,如 br0

    使用 NetworkManager 创建的网桥默认勾选了 "启用 STP",导致容器启动后短时间内网络不通(为什么?),镜像构建时网络不可用,应取消此功能。 不重启网桥的情况下可通过 sudo brctl stp br0 on 动态关闭 stp 功能。

  • fixed-cidr bridge 桥接网络分配给容器的子网段,必须为 bridge 网桥所在网段的子网。

  • iptables=false 禁止设置 iptables 规则。我们额外管理 iptables,避免 docker 污染 iptables(低版本 docker 不清理 iptables ?)。
  • ip-forward=false 不要操作打开 ip-forward 。通常我们已经按需设置打开 ip-forward 了。

docker daemon 配置文件 /etc/docker/daemon.json 示例:

{
	"graph": "/home/repo/docker/",
	"registry-mirrors": [
		"https://registry-vpc.cn-hangzhou.aliyuncs.com"
		],
	"bridge": "nat0",
	"fixed-cidr": "192.168.128.192/27",
	"iptables": false,
	"ip-forward": false
}

操作命令:

sudo bash -c "! test -s /etc/docker/daemon.json && jq -n \"{}\" | sponge /etc/docker/daemon.json"
sudo jq '.bip = "192.168.254.1/24" | .iptables = false | ."ip-forward" = false' /etc/docker/daemon.json | sudo sponge /etc/docker/daemon.json
sudo jq '."registry-mirrors" = [ "https://registry.docker-cn.com" ] | ."insecure-registries" = []' /etc/docker/daemon.json | sudo sponge /etc/docker/daemon.json
sudo jq '."registry-mirrors" = ."registry-mirrors" + [ "https://registry-vpc.cn-hangzhou.aliyuncs.com" ]' /etc/docker/daemon.json | sudo sponge /etc/docker/daemon.json
sudo jq '.dns = [ "192.168.1.1" ]' /etc/docker/daemon.json | sudo sponge /etc/docker/daemon.json
  • systemd 启动时默认设置 -H fd://,表示 systemd 提供 socket,命令行直接启动时不需要指定此参数,默认使用 unix:///var/run/docker.sock
  • -H tcp://[host:port] 指定监听 TCP 端口, --tls* 相关设置配置 TLS 安全校验支持。
  • --config-file 指定 json 配置文件路径(默认 /etc/docker/daemon.json),减少命令行参数配置并更容易管理。
  • graph 设置 docker 服务根目录,目录不存在会自动创建。
  • registry-mirror 配置镜像注册中心的镜像(mirror)站点,支持配置多个,命令行可指定多次,配置文件中使用复数配置名 registry-mirrors 直接配置列表。 配置注册中心镜像(mirror)后,将尝试从该注册中心拉取镜像(替代官方 docker hub,可省略 host 前缀?要求 docker-ce 17.03.2 以上版本?), 拉回后本地 tag 也不带 host 前缀(但 push 时还是必须添加添加 host 前缀)。 可配置为官方中国镜像 https://registry.docker-cn.com , 参考 官方文档
  • 访问镜像默认使用 TLS (https) 加密,如果访问未加密的站点,需要显示指定 insecure-registry/insecure-registries,参考 Deploy a plain HTTP registry
  • 使用自定义网桥,禁用默认网络配置(iptables, ip-forward)。

    设置 --default-gateway= 时报如下错误:

    3月 25 21:52:43 han2017 dockerd[13947]: Error starting daemon: Error initializing network controller: Error creating default "bridge" network: failed to allocate secondary ip address (DefaultGatewayIPv4:192.168.128.1): Address already in use

    看报错信息,docker 尝试为指定网桥设置指定 IP 失败,删除此配置即可。docker 会自动检查指定网桥得到合适的网关配置(?)。 新版本 docker 无此问题(?)。

搭建官方镜像 hub 的镜像站点,registry 服务设置 proxy.remoteurl 为官方 hub 地址即可:

docker run --name registry -d --restart=unless-stopped --net=host -v /var/lib/registry:/var/lib/registry -e REGISTRY_PROXY_REMOTEURL=https://registry.docker-cn.com registry:2
  • 目前搭建镜像站点仅支持官方 hub (?)。

添加 registry, 如果为 http 协议(非 https),则同时配置 insecure-registries

小心: python 会打乱 json 字段的原始顺序。

jq 'del(."registry-mirrors") | del(."insecure-registries")' /etc/docker/daemon.json | sponge /etc/docker/daemon.json
for e in ${HUB:-http://192.168.22.23:5000} ; do
sudo cat /etc/docker/daemon.json | python2 -c 'import sys, json; a = json.load(sys.stdin); 
k = "registry-mirrors"; v = a[k] = dict.get(a, k, []); rUrl = sys.argv[1]; rUrl in v or v.append(rUrl); 
k = "insecure-registries"; from urlparse import urlparse; rObj = urlparse(rUrl); 
'$'\n''if rObj.scheme == "http": v = a[k] = dict.get(a, k, []); h = rObj.hostname + (rObj.port is not None and ":" + str(rObj.port) or ""); h in v or v.append(h); 
'$'\n''print( json.dumps(a, indent=2) )' "${e}" | sudo sponge /etc/docker/daemon.json
done

或者直接覆盖设置第一个 registry:

sudo cat /etc/docker/daemon.json | python2 -c 'import sys, json; a = json.load(sys.stdin); 
k = "registry-mirrors"; a[k] = dict.get(a, k, [""]); rUrl = sys.argv[1]; a[k][0] = rUrl; 
k = "insecure-registries"; from urlparse import urlparse; rObj = urlparse(rUrl); 
'$'\n''if rObj.scheme == "http": a[k] = [ rObj.hostname + (rObj.port is not None and ":" + str(rObj.port) or ""), ]; '$'\n''else: a[k] = []; 
'$'\n''print( json.dumps(a, indent=2) )' http://192.168.22.23:5000 | sudo sponge /etc/docker/daemon.json
  • 典型设置,第一个为官方 hub 镜像站点,第二个为私有 registry 仓库。修改官方 hub 镜像站点时,直接覆盖第一个 registry。

相关技巧:

  • 挂载 /var/cache/apt 等到容器内,可以复用宿主机上的 cache 等文件,方便制作镜像。 不过当前 docker build 不支持 -v 执行挂载,参考 issue #14080

hosts

  • hostess,支持增删查改,支持设置 hosts 路径,不支持多个候选(提示冲突?)。
  • goodhosts, 支持增删查改,功能更简陋。

pssh

pssh 使用 python 编写,官方代码库为 google code parallel-ssh。 现已不再更新,但代码已经稳定。 ubuntu 下可直接从软件仓库安装 pssh 软件包,安装后默认命令名为 parallel-ssh 等。

sudo aptitude install pssh -y

也直接下载源码包,最新版本 pssh-2.3.1.tar.gz, 解压后使用 python 2.4 及以上(包括 python 3.1 及以上)版本即可直接运行。

curl -sSL https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/parallel-ssh/pssh-2.3.1.tar.gz | sudo tar xz -C /opt/

可使用 update-alternatives 设置 pssh 等更简短方便的命令别名:

sudo update-alternatives --install /usr/local/bin/pssh pssh /usr/bin/parallel-ssh 60 --slave /usr/local/bin/prsync prsync /usr/bin/parallel-rsync
sudo update-alternatives --install /usr/local/bin/pssh pssh /opt/pssh-2.3.1/bin/pssh 40 --slave /usr/local/bin/prsync prsync /opt/pssh-2.3.1/bin/prsync

pssh 很多选项也可以使用环境变量设置(全局默认值,优先级低于命令行参数),代码 psshlib/cli.py 可看到相关选项与环境变量的对应关系。 常用全局默认设置如下:

  • -i, --inline,输出执行命令的标准输出和标准错误,PSSH_INLINE。建议 PSSH_INLINE=1
  • -O OPTION, --option=OPTION,附加 ssh 选项,PSSH_OPTIONS。 可包含多个空格分割的 token,每个 token 为一个完整的 ssh 选项,因此 ssh 选项 key/value 应用 = 连接(不要用空格分割)。 可设置 PSSH_OPTIONS="StrictHostKeyChecking=no"

direnv

参考:https://direnv.net/

sudo aptitude install direnv -y

~/.bashrc 添加:

eval "$(direnv hook bash)"

direnv edit 使用环境变量 EDITOR 定义的编辑器,必须配置此环境变量,如 EDITOR=vim

sdkman

sdkman 使用 bash,不兼容基本 sh,只能在 .bashrc 中引入。

  • 环境变量配置 SDKMAN_OFFLINE_MODE=true

  • 配置文件 ~/.sdkman/etc/config,设置 sdkman_colour_enable=false

    sed -r -e 's#^(sdkman_colour_enable)=.*$#\1=false#g' ~/.sdkman/etc/config -i
  • 不要自动检查 sdkman 版本。

    sdkman (版本 5.6.1+290 及以上?) 执行非 update 命令时尝试自动检查 sdkman 版本更新(每 24 小时检查一次?)。 sdkman-main.sh 中代码如下:

      # Check version and candidates cache
      if [[ "$COMMAND" != "update" ]]; then
          ___sdkman_check_candidates_cache "$SDKMAN_CANDIDATES_CACHE" || return 1
          ___sdkman_check_version_cache
      fi

    执行检查的代码在 sdkman-cache.sh, 可注释掉如下一行避免检查:

          SDKMAN_REMOTE_VERSION=$(__sdkman_secure_curl_with_timeouts "$version_url")

    sed 命令:

    sed -r -e '/^(\s|#)*SDKMAN_REMOTE_VERSION=\$\(__sdkman_secure_curl/ s/(^\s*)#?(SDKMAN)/\1#\2/g' ~/.sdkman/src/sdkman-cache.sh -i

    注意: 但设置后 sdkman 将不能检查更新版本,后续需要手动升级 sdkman 版本时,需要先去掉此修改。

python 环境

通常可使用 GNU/Linux 发行版系统自带的包管理工具安装 python 解释器,建议优先考虑 python3 。 操作系统软件包管理通常已包含常用 python 软件包,可作为系统全局安装。

sudo aptitude install python3 python3-virtualenv python3-pip -y

用户 python 应用建议创建独立的 virtualenv 环境并使用 pip 安装软件包,这样可以使用最新的软件包,同时避免应用依赖冲突。 创建 virtualenv 时默认会安装 pip 等基本软件包。 pip 用户级别默认配置为 $HOME/.config/pip/pip.conf,virtualenv 下配置为 $VIRTUAL_ENV/pip.conf。 通常可配置 pypi 镜像加速 python 软件包安装,详情参考 pip 配置说明

(默认官方地址 https://pypi.python.org/simple )。

[global]
index-url = https://mirrors.aliyun.com/pypi/simple/
#trusted-host = mirrors.aliyun.com
  • global 是全局配置,剩下的每段为对应命令的配置。
  • 配置项与命令行参数长选项同名,如查看 python3 -m pip install --help 就可以知道 install 的相关配置项。
  • index-url 配置软件包索引地址(默认官方地址 https://pypi.python.org/simple/ ),包含海量内容,不要直接访问(否则卡死浏览器)。
  • trusted-host 配置信任主机,链接不安全但信任主机时可以使用。

创建应用 virtualenv 环境:

$ python3 -m virtualenv --python python3 app/
Already using interpreter /usr/bin/python3
Using base prefix '/usr'
New python executable in /home/hanyong/opt/app/bin/python3
Also creating executable in /home/hanyong/opt/app/bin/python
Installing setuptools, pkg_resources, pip, wheel...done.

$ python3 -m pip --version
pip 8.1.1 from /usr/lib/python3/dist-packages (python 3.5)

$ ./app/bin/pip --version
pip 9.0.2 from /home/hanyong/opt/app/lib/python3.5/site-packages (python 3.5)

$ ./app/bin/python3 -c 'import sys; print(sys.path)'
['', '/home/hanyong/opt/app/lib/python35.zip', '/home/hanyong/opt/app/lib/python3.5', '/home/hanyong/opt/app/lib/python3.5/plat-x86_64-linux-gnu', '/home/hanyong/opt/app/lib/python3.5/lib-dynload', '/usr/lib/python3.5', '/usr/lib/python3.5/plat-x86_64-linux-gnu', '/home/hanyong/opt/app/lib/python3.5/site-packages']
  • --python 指定 python 解释器,这是必须的,默认使用的是 python2 (虽然提示 Already using ... ?)。
  • 系统上同时安装了多个 python 版本,所以使用 python3 -m pip 明确指定使用的 python 版本。 virtualenv 下只有一个版本,可直接执行 pip 。可看到 virtualenv 下自动安装了新版本的 pip 。
  • virtualenv 下的脚本默认是写死 virtualenv 目录的绝对路径的。不能修改路径,否则新安装的脚本无法使用。所以不要改路径,要么全部重新安装一遍。
  • virtualenv 创建完后可修改为相对路径(使用 #!/usr/bin/env python),但这样要求配置好 PATH ,通用性也不好(并且有坑?),不推荐。

既然 virtualenv 目录不方便移动,可重新创建,可将其与应用配置和数据分开。 应用根目录模拟 Linux 系统目录结构,则可将其安装在应用 usr/ (或更独立的 python3/ ?)目录下。 为了实现可移植性,其他应用配置也需要考虑适配相对路径。

$ python3 -m virtualenv --python python3 app/usr/
# ... ...

$ source app/usr/bin/activate

(usr) 
$ which -a python3
/home/hanyong/opt/app/usr/bin/python3
/usr/bin/python3

(usr) 
$ pip --version
pip 9.0.2 from /home/hanyong/opt/app/usr/lib/python3.5/site-packages (python 3.5)

(usr) 
$ deactivate 

$ pip --version
pip 8.1.1 from /usr/lib/python2.7/dist-packages (python 2.7)
  • source virtualenv 目录下的 bin/activate 文件可自动设置 PATH 等环境变量,方便在 shell 下调用 virtualenv 下安装的命令。 经测试 man 手册也可以查看。
  • PS1 提示符自动增加 virtualenv 名字前者,默认为其目录名(所以为 usr)。创建 virtualenv 时可使用 --prompt 自定义设置。
  • 执行 deactivate 可退出 virtualenv 相关设置。

pip 安装指定版本软件包:

pip install pyzmq==16.0.4

输入不存的版本(如空?),就会提示可用的版本,可作为查询可用版本的小技巧。

$ pip install pyzmq==
Collecting pyzmq==
  Could not find a version that satisfies the requirement pyzmq== (from versions: 2.0.7, 2.0.8, 2.0.10, 2.0.10.1, 2.1.1, 2.1.4, 2.1.7, 2.1.9, 2.1.10, 2.1.11, 2.2.0, 2.2.0.1, 13.0.0, 13.0.1, 13.0.2, 13.1.0, 14.0.0, 14.0.1, 14.1.0, 14.1.1, 14.2.0, 14.3.0, 14.3.1, 14.4.0, 14.4.1, 14.5.0, 14.6.0, 14.7.0, 15.0.0, 15.1.0, 15.2.0, 15.3.0, 15.4.0, 16.0.0, 16.0.1, 16.0.2, 16.0.3, 16.0.4, 17.0.0b1, 17.0.0b2, 17.0.0b3, 17.0.0b4, 17.0.0)
No matching distribution found for pyzmq==

node 环境安装配置

安装 node:

使用 nvmnvs(推荐)安装。

  • 第一次执行任意 nvs 命令即会下载 bootstrap node 作为 nvs 本身的解析器,默认从 defaults.json 文件中解析下载 URL, 默认为 https://nodejs.org/dist/ ,可临时修改为淘宝镜像 https://npm.taobao.org/mirrors/node/
  • source nvs.sh 后 nvs(函数)才能修改 $PATH
  • 第一次执行 nvs remote(管理各种 node 的下载 URL)时自动拷贝默认配置到 settings.json,之后默认配置文件可以还原。
  • nvs add 安装 node 版本,如 nvs add node/6
  • nvs use 使用指定版本,如 nvs use node/6
  • nvs link 设置默认版本。source nvs.sh 时自动添加默认版本到 $PATH(bug: 会重复添加?)。 不推荐使用。
  • nvs install 自动修改 shell 配置文件,bash 下默认添加 source nvs.sh 到 ~/.bashrc 文件(shell 函数不能从父进程继承)。 同时可手动在 .profile 文件中添加 nvs use 设置登录 shell 默认的 node 版本。 注意:nvs uninstall 还会进一步移除 PATH 设置和默认版本(不建议设置默认版本(?),可忽略)设置(副作用?)。
git clone git@github.com:jasongin/nvs.git
cd nvs
sed -e 's#https://nodejs.org/dist/#https://npm.taobao.org/mirrors/node/#' defaults.json -i
. nvs.sh
nvs remote default
git checkout .
nvs add node/10
nvs use node/10
# 修改 .bashrc 。可选手动修改 .profile(?)
#nvs install

手动修改 ~/.profile ,添加如下两行即可:

. $HOME/workspace/nvs/nvs.sh
nvs use node/10

配置 npm:

用户默认配置文件为 ~/.npmrc。 使用 npm config set <key> <value> 修改配置,npm config edit 使用编辑器编辑(可看到可配置项及默认值),npm config list 查看用户配置。 参考 npm help config (man npm-config), man npmrc

npm config set registry https://registry.npm.taobao.org/
# 升级 npm
npm install -g npm
  • 使用镜像搜索可能有问题,搜索时可能需要设置回官方仓库。可包装为一条简单命令 npm-search
npm search --registry=https://registry.npmjs.org/ jquery
  • 查询指定 package 可用的版本号,可用 npm view <pkg> versions,view 命令还可用查看其他更多信息,参考 npm help view

  • 初始化 node 项目。

npm init -y
# 安装依赖
npm install semantic-ui --production --save jquery
# 设置 direnv
echo "layout node" > .envrc
# 非开发环境可直接设置 NODE_ENV=production
echo "export NODE_ENV=production" >> .envrc
direnv allow .

angular 项目(Angular CLI 7.3.1, Angular 7.2.5, 2019-02-18)。

ng new hello-ng --defaults --routing --style scss
cd hello-ng/

上述命令行 style 是在 project 上设置,style 也可以创建后在整个 workspace 上设置。 修改后已有文件, src/styles.scss 在 angular.json 中的配置路径, 及 component 代码中的路径引用等需要手动订正。 (idea 支持重命名文件时自动订正 component 的代码引用?)

ng config schematics.@schematics/angular:component.style scss
ng config projects.ops.architect.build.options.styles '[ "src/styles.scss" ]'
ng config projects.ops.architect.test.options.styles '[ "src/styles.scss" ]'

附加配置修改(可写成辅助脚本 ng-init.sh ?):

# 代码风格使用双引号
jq '.rules.quotemark = [ true, "double", "avoid-escape" ]' tslint.json | sponge tslint.json
# 自动推导基本类型时, 类字段允许显式写出类型
jq '.rules."no-inferrable-types" = [ true, "ignore-params", "ignore-properties" ]' tslint.json | sponge tslint.json
for e in $(ng generate --help=json | jq '.options | .[0] | .subcommands | keys | .[]' -r) ; do ng generate ${e} --help | grep -F -e --lint-fix && echo "${e}" | tee -a ~/tmp/a.txt ; done
for e in $(cat ~/tmp/a.txt) ; do ng config schematics.@schematics/angular:${e}.lintFix true ; done
ng lint --fix

# 配置 base-href
ng config projects.hello-ng.architect.build.options.baseHref /hello/
ng config projects.hello-ng.architect.build.options.outputPath dist/hello/

ng config projects.hello-ng.architect.serve.options.baseHref /hello/

# 添加 FormsModule HttpClientModule .
# 参考: https://angular.io/tutorial/toh-pt1#two-way-binding .
sed -r -e '/^import\b.*\bNgModule\b/ a import { FormsModule, ReactiveFormsModule, } from "@angular/forms";'$'\\\nimport { HttpClientModule } from "@angular/common/http";' \
-e '/^\s*BrowserModule\b/ { s#,?$#,# ; a'$'\\\n    FormsModule,\\\n    ReactiveFormsModule,\\\n    HttpClientModule,\n}' src/app/app.module.ts -i

# 配置使用 hash location
sed -re 's#(RouterModule.forRoot\(routes).*?(\))#\1, { useHash: true, }\2#g' src/app/app-routing.module.ts -i

# 配置反向代理
jq -n '{ "/hello/api/": { "target": "http://localhost:8080", "secure": false, }, }' > proxy.conf.json
ng config projects.hello-ng.architect.serve.options.proxyConfig proxy.conf.json

# 安装使用 bootstrap .
# 参考: https://medium.com/@tomastrajan/how-to-build-responsive-layouts-with-bootstrap-4-and-angular-6-cfbb108d797b
npm install -P bootstrap
sed -e '$ a @import "~bootstrap/scss/bootstrap";' src/styles.scss -i
  • 项目 ".editorconfig" 默认使用 2 空格缩进,可将 [src/**] (或 [src/app/**] ?) 下的文件修改为 tab 缩进, 缩进大小为 4 。
[src/**]
indent_style = tab
indent_size = 4

同步修改 tslint.json 添加配置如下:

  • 使用 tab 缩进时函数参数("parameters")对齐检查不通过,可去掉该检查。
  • ng generate 默认产生代码为 2 空格缩进, tslint auto-fix 只修改缩进字符类型, 不修改缩进大小(重新格式化), 因此设置缩进 2 使其将 2 个空格转成一个 tab。tab 的实际显示尺寸由 editorconfig 控制。
	"align": [
		true,
		"arguments",
		"statements",
		"members",
		"elements"
	],
	"indent": [
		true,
		"tabs",
		2
	]
  • 为保证一致性,每个页面对应统一的 path,不要为一个页面配置多个 path 避免混淆。 主页(默认页面)可配置 redirectTo 跳转 (若使用 "" 访问主页,主页必须在最上层,下层 path 必须是层次结构的,下层页面的 path 不能使用 ""(每层 path 不能为空),因此不能作为最上层主页。)
{ path: "", redirectTo: "list", pathMatch: "full", },

没有页面对应的 path 必须唯一固定,以便在页面中使用相对路径引用其他页面。 如果本页面 path 改变,则所有对其他页面的相对路径引用都要对应修改(除非使用绝对路径引用其他页面?)。

2019-04-30 订正:angular 支持路由 "" 到子模块主页,模块框架页用 routerLink="." 链接到模块主页。 使用 routerLink="" 则为应用主页(?)。 angular 可自动根据 URL 设置导航按钮的激活状态。 多层导航时,上层菜单项导航到本层主页,为了使这两个导航按钮有不同的状态控制, 可使用非空 path(而不是 "")作为模块主页(推荐?),避免导航按钮 URL 相同。

如果一个模块的多个页面希望看到不同导航菜单,可将差异部分的导航菜单下沉到模块子页面中。

pathMatch 路径匹配默认为 "prefix" 前缀匹配, 模块主页同时也是其他模块的前缀,因此应修改为 "full" 完整匹配。

子模块路由示例:

const routes: Routes = [{
	path: "vpc",
	component: VpcComponent,
	children: [
		{ path: "", redirectTo: "list", pathMatch: "full", },
		// { path: "", component: VpcListComponent, pathMatch: "full", },
		{ path: "list", component: VpcListComponent, },
		{ path: "edit", component: VpcEditComponent, },
	],
}];
  • angular 默认使用单引号做字符串编码规范,为兼容其他语言建议修改为双引号。相关讨论参考:

    ng new <name> 生成项目的 tslint.json 中可看到如下配置:

      "quotemark": [
        true,
        "single"
      ],

    可修改为:

      "quotemark": [
        true,
        "double",
        "avoid-escape"
      ],

    遍历找到支持 --lint-fix 的 generate 选项。

    for e in $(ng generate --help=json | jq '.options | .[0] | .subcommands | keys | .[]' -r) ; do ng generate ${e} --help | grep -F -e --lint-fix && echo "${e}" | tee -a ~/tmp/a.txt ; done

    相关选项设置 lintFix

    for e in $(cat ~/tmp/a.txt) ; do ng config schematics.@schematics/angular:${e}.lintFix true ; done

    另外需要注意, WebStorm (2018.1.5) 中调用 new "Angular CLI..." 时需要在根目录下调用, 否则 lintFix 时会报 ENOENT: no such file or directory, scandir '.../hello-ng/src/app/src/app',其中 src/app 重复出现了 2 次。

  • tslint 添加设置 "object-literal-shorthand": false,不强制使用简写,参考 object-literal-shorthand

  • Component HTML 模板默认会被剔除掉空格,这有时会轻微影响布局(控件间不留空隙?)。 @Component 添加设置 preserveWhitespaces: true 可避免此问题。

  • 可以先建一个空的 workspace,再手动创建 project 。

ng new --defaults --create-application=false hello-ng
ng generate application hello-ng --defaults --routing
# generate app-routing module
#ng generate module app-routing --flat --module=app

但注意,默认创建的 project 配置如下:

"projects": {
  "hello-ng": {
    "root": "",
    "sourceRoot": "src",
    "projectType": "application",
    "prefix": "app",
    // ... ...
  },
  "hello-ng-e2e": {
    "root": "e2e/",
    "projectType": "application",
    "prefix": "",
    // ... ...
  },

手动创建的 project 配置如下:

"projects": {
  "hello-ng": {
    "root": "projects/hello-ng/",
    "sourceRoot": "projects/hello-ng/src",
    "projectType": "application",
    "prefix": "app",
    // ... ...
  },
  "hello-ng-e2e": {
    "root": "projects/hello-ng-e2e/",
    "projectType": "application",
    "prefix": "",
    // ... ...
  },

编辑文件 proxy.conf.json 内容如下:

{
  "/ops/api/": {
    "target": "http://localhost:8080",
    "secure": false
  }
}

添加 serve 添加配置 proxyConfig:

ng config projects.hello-ng.architect.serve.options.proxyConfig proxy.conf.json

即可实现反向代理联调后端服务器。

  • 生成最终静态文件。
ng build --base-href /hello/ --output-path dist/hello/ --prod

初始 --output-path 应为空目录(默认为 dist/<project>),每次 build 会清空此目录(?)。

base-hrefdeploy-url 的区别, 参考: https://stackoverflow.com/questions/51182322/whats-the-difference-between-base-href-and-deploy-url-parameters-of-angular

base-href is being used by routing and deploy-url is for assets. In most cases base-href is enough.

相关配置也可以直接修改 angular project 配置。

ng config projects.hello-ng.architect.build.options.baseHref /hello/
ng config projects.hello-ng.architect.build.options.outputPath dist/hello/

ng config projects.hello-ng.architect.serve.options.baseHref /hello/

angular routing 路径默认直接拼 URL, 而传统 angularjs 1.x 是使用 hash fragment。 angular 也可以修改使用传统的 hash location 。 参考:https://angular.io/guide/router#appendix-locationstrategy-and-browser-url-styles

RouterModule.forRoot(routes, { useHash: true })

其他相关项目:

可在 component 初始化时将其放到全局作用域 window 上,方便在浏览器控制台中访问测试:

ngOnInit() {
  (window as any).vm = this;
  // ... ...
}

引入 jQuery ,参考: https://blog.csdn.net/home_zhang/article/details/77992734

npm install -P jquery
npm install -P @types/jquery

代码中使用如下代码引入:

import * as jQuery from "jquery";

或者编辑 project 的 scripts 配置,设置 js 路径(未测试),参考: https://medium.com/@swarnakishore/how-to-include-and-use-jquery-in-angular-cli-project-592e0fe63176

关于 FROM 参考: https://angular.io/guide/forms-overview . TODO 手动调用 formControl.setValue() 后如何请求更新 UI 。

latex 环境

在线编辑:https://www.sharelatex.com/

sudo aptitude install texlive -y
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys D6BC243565B2087BC3F897C9277A7293F59E4889
echo "deb http://miktex.org/download/ubuntu xenial universe" | sudo tee /etc/apt/sources.list.d/miktex.list
sudo apt-get update
sudo apt-get install miktex

执行 latex(或 miktex-latex)命令生成 dvi 文件,可使用 xdvi 查看。

支持中文(参考:http://blog.csdn.net/u014803202/article/details/50410748):

转为 PNG 图片(参考:https://tex.stackexchange.com/questions/11866/compile-a-latex-document-into-a-png-image-thats-as-short-as-possible):