npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

san-loader-next

v0.1.0

Published

San single-file-component loader for Webpack

Downloads

1

Readme

san-loader-next

San-Loader 是基于 webpack 的工具,允许开发者书写 San 单文件的方式来进行组件开发。开发环境 Node.js v14

<template>
  <div class="content">Hello {{name}}!</div>
</template>

<script>
  export default {
    initData() {
      return {
        name: "San",
      };
    },
  };
</script>

<style>
  .content {
    color: blue;
  }
</style>

San 单文件在写法上与 Vue 类似,San-Loader 会将 templatescriptstyle 等标签块当中的内容和属性提取出来,并交给 webpack 分别进行处理。最终单文件对外返回的将是一个普通的 San 组件类,我们可以直接使用它进行 San 组件的各种操作:

import App from "./App.san";
let app = new App();
app.attach(document.body);

使用方法

通过 npm 进行 San-Loader 的安装:

npm install --save-dev san-loader

然后在 webpack 的配置文件上增加一条规则应用到 .san 文件上,并且增加一个 SanLoaderPlugin:

const SanLoaderPlugin = require("san-loader/lib/plugin");

module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.san$/,
        loader: "san-loader",
      },
      // ...
    ],
  },
  plugins: [new SanLoaderPlugin()],
};

如前面提到,San-Loader 会将单文件的各个部分拆分出来,并交给其他的 Loader 来进行资源处理,因此还需要配置各个模块的处理方法,比如:

const SanLoaderPlugin = require("san-loader/lib/plugin");

module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.san$/,
        loader: "san-loader",
      },
      {
        test: /\.js$/,
        loader: "babel-loader",
      },
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"],
      },
      {
        test: /\.html$/,
        loader: "html-loader",
      },
      // ...
    ],
  },
  plugins: [new SanLoaderPlugin()],
};

在默认情况下,templatescriptstyle 会分别采用 .html.js.css 所对应的 Loader 配置进行处理,当然我们也可以在相应的标签上添加 lang 属性来指定不同的语言处理比如:

<style lang="less">
  @grey: #999;

  div {
    span {
      color: @grey;
    }
  }
</style>

这样,对应的样式模块就可以当成 .less 文件进行处理,只需要配置上相应的 Loader 即可。

// ...
module.exports = {
  // ...
  module: {
    rules: [
      // ...
      {
        test: /\.less$/,
        use: ["style-loader", "css-loader", "less-loader"],
      },
    ],
  },
};

更加完整的 webpack 配置,可以参考示例:

Options

| Name | Type | Default | Description | | :----------------: | :---------------------------------------------: | :------: | :------------------------------------------------------------------------------------------ | | compileTemplate | {'none'|'aPack'|'aNode'} | 'none' | 将组件的template 编译成aPackaNode默认不编译,详细见下面说明 | | esModule | {Boolean} | false | san-loader 默认使用 CommonJS 模块语法来生成 JS 模块,将该参数设为 true 可以改用 ES 模块语法 | | autoAddScriptTag | {Boolean} | false | 是否自动添加 script 标签,现在 .san 组件中 script 是可选的了 |

特殊说明:

compileTemplate:San 组件的string类型的template通过编译可以返回aNode结构,在定义组件的时候,可以直接使用aNode作为 template,这样可以减少了组件的template编译时间,提升了代码的执行效率,但是转成aNode的组件代码相对来说比较大,所以在[email protected]引入的概念的aNode压缩结构aPack使用aPack可以兼顾体积和效率的问题。san-loader 中的compileTemplate就是来指定要不要将组件编译为aPack/aNode如果只想,单文件使用compileTemplate编译成对应的aPack或者aNode,可以直接在template上面写:<template compileTemplate="aPack">。 使用 pug 等预处理模版语言时,compileTemplate 不生效,请使用 san-anode-loader

扩展阅读

单文件写法

template

单文件中 template 模块的主要作用是提供一种更为便捷的方式来书写组件的 template 字符串。在配置 webpack 的时候,需要对 template 部分配置 raw-loader、html-loader 等等。其中如果 template 当中需要使用到图片、字体文件,建议采用 html-loader 配合 url-loader 的形式完成相关配置。例如:

<template>
  <div>
    <img src="../assets/logo.png" />
  </div>
</template>

则需要在 webpack 配置文件当中增加如下配置:

module.exports = {
  module: {
    rules: [
      // ...
      {
        test: /\.html$/,
        loader: "html-loader",
      },
      {
        test: /\.png$/,
        loader: "url-loader",
      },
    ],
  },
};

template 部分可以省略不写,直接在 script 模块当中定义也是可以的:

<script>
  export default {
    template: "<div>{{name}}</div>",
  };
</script>

template 模块也支持通过 src 标签引入 template 文件:

<template src="./component-template.html"></template>

注意:html-loader 最新版本在生产环境(production)会默认开启minimize=true,会导致 san 解析 template 失败,所以使用 html-loader 的时候建议开启minimize=false

script

script 模块必须通过 export default 将组件的 JS 代码导出。在写法上,支持类似 Vue 的写法:

<script>
  export default {
    initData() {
      return {
        name: "San",
      };
    },
  };
</script>

San-Loader 会自动为导出为普通对象的模块外部自动包上 san.defineComponent 使之成为真正的 San 组件。

import script from "./App.san?san&type=script&lang=js";
import san from "san";
// ...
export default san.defineComponent(script);

我们也可以通过 class 的方式:

<script>
  import san from "san";
  export default class App extends san.Component {
    initData() {
      return {
        name: "San",
      };
    }
  }
</script>

也可以配合 san-store 一起使用,比如:

<script>
  import san from "san";
  import { store, connect } from "san-store";
  import { builder } from "san-update";

  // ...
  export default connect.san({
    name: "user.name",
  })(
    san.defineComponent({
      // ...
    })
  );
</script>

总之在写法上与普通的 San 组件不存在太大区别,区别的地方只在于 template 和 style 的部分可以放到别的模块里进行书写。

当组件不依赖数据和计算的时候,script 块可以省略不写。

与 template 相似,script 模块也可以通过定义 src 属性导入相应的组件代码:

<script src="./component-script.js"></script>

在默认情况下,script 模块的内容会被当成 .js 文件进行处理,如改成 TypeScript 的话,可以通过在 script 标签上添加属性 lang="ts" 将该模块标记为 .ts 文件,然后自行在 webpack 配置文件当中添加对 .ts 文件的处理 Loader 即可:

<script lang="ts">
  // ...
</script>

这时候需要修改ts-loader配置:

{
    test: /\.ts$/,
    loader: 'ts-loader',
    options: { appendTsSuffixTo: [/\.san$/] }
}

或者babel-loader的配置:

{
    test: /\.ts$/,
    use: [
        {
            loader: 'babel-loader',
            options: {
                plugins: [
                    require.resolve('@babel/plugin-proposal-class-properties'),
                    require.resolve('san-hot-loader/lib/babel-plugin')
                ],
                presets: [
                    [
                        require.resolve('@babel/preset-env'),
                        {
                            targets: {
                                browsers: '> 1%, last 2 versions'
                            },
                            modules: false
                        }

                    ],
                    // 下面配置 allExtensions
                    [require.resolve('@babel/preset-typescript'), {allExtensions: true}]
                ]
            }
        }
    ]
}

允许非 CSS Modules

也可以指定部分 style 标签使用 CSS Modules,其他仍然是普通的全局 CSS:

<style module>
  /* 这里是 CSS Modules */
</style>

<style>
  /* 这里是全局 CSS */
</style>

san-loader 会给带 module<style> 添加对应的 resourceQuery,所以你可以这样配置:

// webpack.config.js 省略上下文
rules: [
  {
    test: /\.css$/,
    oneOf: [
      // 这里匹配 `<style module>`
      {
        resourceQuery: /module/,
        use: [
          "style-loader",
          {
            loader: "css-loader",
            options: {
              modules: {
                localIdentName: "[local]_[hash:base64:5]",
              },
              localsConvention: "camelCase",
              sourceMap: true,
            },
          },
        ],
      },
      // 这里匹配 `<style>`
      {
        use: [
          {
            loader: "style-loader",
          },
          {
            loader: "css-loader",
            options: {
              sourceMap: true,
            },
          },
        ],
      },
    ],
  },
];

LICENSE

MIT 2021 Baidu.Inc