├── .babelrc
├── .gitignore
├── .storybook
├── addons.js
├── config.js
├── presets.js
└── webpack.config.js
├── README.md
├── package.json
├── public
├── favicon.png
├── global.css
└── index.html
├── src
├── App.svelte
├── common
│ └── helpers.ts
├── components
│ └── button
│ │ ├── Button.svelte
│ │ ├── Button2.scss
│ │ ├── Button2.svelte
│ │ └── ButtonData.ts
├── main.ts
└── styles
│ ├── defaults.scss
│ ├── icons.scss
│ └── variables.scss
├── stories
├── button.stories.ts
└── button2.stories.ts
├── svelte.config.js
├── tsconfig.json
├── webpack.common.js
├── webpack.dev.js
├── webpack.parts.js
└── webpack.prod.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["@babel/preset-typescript", { "targets": "last 2 versions, ie 11"}]
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | package-lock.json
4 | yarn.lock
5 | .idea/
6 |
7 | build/
8 |
--------------------------------------------------------------------------------
/.storybook/addons.js:
--------------------------------------------------------------------------------
1 | import '@storybook/addon-actions/register';
2 | import '@storybook/addon-links/register';
3 | import '@storybook/addon-viewport/register';
4 | import '@storybook/addon-knobs/register';
5 |
--------------------------------------------------------------------------------
/.storybook/config.js:
--------------------------------------------------------------------------------
1 | import { configure } from '@storybook/svelte';
2 |
3 | // automatically import all files ending in *.stories.js
4 | configure(require.context('../stories', true, /\.stories\.[jt]s$/), module);
5 |
--------------------------------------------------------------------------------
/.storybook/presets.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | "@storybook/preset-typescript",
3 | {
4 | name: '@storybook/preset-scss',
5 | options: {
6 | cssLoaderOptions: {
7 | sourceMap: true
8 | }
9 | }
10 | }];
11 |
--------------------------------------------------------------------------------
/.storybook/webpack.config.js:
--------------------------------------------------------------------------------
1 | const {aliases, scssAliases, onwarn} = require("../webpack.parts");
2 | const merge = require('webpack-merge');
3 | const {CheckerPlugin} = require('awesome-typescript-loader');
4 |
5 |
6 | module.exports = ({config, mode}) => {
7 | // console.dir(config, { depth: null });
8 | let mergedConfig = merge.smart(config, {
9 | module:
10 | {
11 | rules: [
12 | {
13 | test: /\.(svelte|html)$/,
14 | loader: 'svelte-loader',
15 | options: {
16 | onwarn: onwarn,
17 | preprocess: require('svelte-preprocess')({
18 | scss: {
19 | importer: [
20 | scssAliases(aliases),
21 | ],
22 | }
23 | })
24 | }
25 | },
26 | ]
27 | },
28 | });
29 | mergedConfig.resolve.alias = {...mergedConfig.resolve.alias, ...aliases};
30 | mergedConfig.plugins.push(new CheckerPlugin());
31 | //console.dir(mergedConfig, {depth: null});
32 | return mergedConfig;
33 | };
34 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Svelte, Typescript, SASS, Storybook, Webpack template
2 |
3 | This project template was based on the [Svelte](https://svelte.dev) webpack template. It lives at https://github.com/sveltejs/template-webpack.
4 |
5 | It was modified to include
6 | - Typescript
7 | - Sass
8 | - Storybook
9 |
10 | To create a new project based on this template using [degit](https://github.com/Rich-Harris/degit):
11 |
12 | ```bash
13 | npx degit nitro52/svelte-typescript-sass-template svelte-app
14 | cd svelte-app
15 | ```
16 |
17 | *Note that you will need to have [Node.js](https://nodejs.org) installed.*
18 |
19 |
20 | ## Get started
21 |
22 | Install the dependencies...
23 |
24 | ```bash
25 | cd svelte-app
26 | npm install
27 | ```
28 |
29 | ...then start webpack:
30 |
31 | ```bash
32 | npm run dev
33 | ```
34 |
35 | Navigate to [localhost:4000](http://localhost:4000). You should see your app running. Edit a component file in `src`, save it, and the page should reload with your changes.
36 |
37 | ### Limitations
38 | #### Typescript/Sass
39 | Typescript and Sass support for `.svelte` files are added via the `svelte-preprocessor`.
40 | It requires using the `lang` or `type` attributes on the `style` and `script` elements.
41 | Within the script block this should work but inside `.svelte` files support varies based on the IDE you use. It may build but your IDE still shows errors
42 |
43 | Importing separate Typescript and Sass files should work fine.
44 |
45 | #### Aliases
46 | Currently to use webpack style aliases during imports they need to be defined in `webpack.config', as a custom sass scssAliases to enable in sass and in tsconfig.json to enable importing in typescript
47 |
48 | I'm currently looking for a way to share this logic but for now you must update aliases in `webpack.common.js` as well as `packages.json`
49 |
50 | ## Storybook
51 | [Storybook](https://storybook.js.org/) has been setup to allow designing components in isolation. There are many Story book [addons](https://storybook.js.org/addons/) that can be added to extend the features
52 |
53 | Run storybook with
54 |
55 | ```bash
56 | npm run storybook
57 | ```
58 | Navigate to [localhost:4061](http://localhost:4060). You should see your component stories.
59 |
60 | ### Stories
61 | Storybook is configured to load stories from the `stories` folder that end in `.stories.js` or `.stories.ts`
62 |
63 | This project shows 2 button examples, one button uses scss within a svelte file, the other imports a scss file using the src attribute
64 |
65 | ### Removing Storybook
66 | If you don't want storybook remove the following
67 |
68 | **Folders**
69 | - `.storybook`
70 | - `stories`
71 |
72 | **NPM Packages**
73 | ```
74 | "@storybook/addon-actions": "^5.2.4",
75 | "@storybook/addon-knobs": "^5.2.5",
76 | "@storybook/addon-links": "^5.2.4",
77 | "@storybook/addon-viewport": "^5.2.5",
78 | "@storybook/addons": "^5.2.4",
79 | "@storybook/preset-scss": "^1.0.2",
80 | "@storybook/preset-typescript": "^1.1.0",
81 | "@storybook/svelte": "^5.2.4",
82 | "react-docgen-typescript-loader": "^3.3.0",
83 | ```
84 | Note - `react-docgen-typescript-loader` is a dependency of the @storybook/preset-typescript and will be removed in a future version
85 |
86 | Lastly remove the `storybook` script from your `packages.json` `scripts` section
87 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "svelte-app",
3 | "version": "1.0.0",
4 | "devDependencies": {
5 | "@babel/cli": "^7.7.4",
6 | "@babel/core": "^7.7.4",
7 | "@babel/preset-typescript": "^7.7.4",
8 | "@fortawesome/fontawesome-free": "^5.11.2",
9 | "@pyoner/svelte-types": "^3.4.4-2",
10 | "@storybook/addon-actions": "^5.2.8",
11 | "@storybook/addon-knobs": "^5.2.8",
12 | "@storybook/addon-links": "^5.2.8",
13 | "@storybook/addon-viewport": "^5.2.8",
14 | "@storybook/addons": "^5.2.8",
15 | "@storybook/preset-scss": "^1.0.2",
16 | "@storybook/preset-typescript": "^1.1.0",
17 | "@storybook/svelte": "^5.2.8",
18 | "awesome-typescript-loader": "^5.2.1",
19 | "babel-loader": "^8.0.6",
20 | "clean-webpack-plugin": "^3.0.0",
21 | "copy-webpack-plugin": "^5.0.5",
22 | "css-loader": "^3.2.1",
23 | "mini-css-extract-plugin": "^0.8.0",
24 | "node-sass": "^4.13.0",
25 | "node-sass-magic-importer": "^5.3.2",
26 | "react-docgen-typescript-loader": "^3.6.0",
27 | "sass-loader": "^8.0.0",
28 | "style-loader": "^1.0.1",
29 | "svelte": "^3.16.0",
30 | "svelte-loader": "^2.13.6",
31 | "svelte-preprocess": "^3.2.6",
32 | "ts-loader": "^6.2.1",
33 | "typescript": "^3.7.2",
34 | "webpack": "^4.41.2",
35 | "webpack-cli": "^3.3.10",
36 | "webpack-dev-server": "^3.9.0",
37 | "webpack-merge": "^4.2.2"
38 | },
39 | "scripts": {
40 | "build": "webpack --config webpack.prod.js",
41 | "dev": "webpack-dev-server --open --config webpack.dev.js",
42 | "storybook": "start-storybook -p 4061"
43 | },
44 | "dependencies": {}
45 | }
46 |
--------------------------------------------------------------------------------
/public/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rburnham52/svelte-typescript-sass-template/047757a8e4b9d7df5e76632e9a9516b4f765c042/public/favicon.png
--------------------------------------------------------------------------------
/public/global.css:
--------------------------------------------------------------------------------
1 | html, body {
2 | position: relative;
3 | width: 100%;
4 | height: 100%;
5 | }
6 |
7 | body {
8 | color: #333;
9 | margin: 0;
10 | padding: 8px;
11 | box-sizing: border-box;
12 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
13 | }
14 |
15 | a {
16 | color: rgb(0,100,200);
17 | text-decoration: none;
18 | }
19 |
20 | a:hover {
21 | text-decoration: underline;
22 | }
23 |
24 | a:visited {
25 | color: rgb(0,80,160);
26 | }
27 |
28 | label {
29 | display: block;
30 | }
31 |
32 | input, button, select, textarea {
33 | font-family: inherit;
34 | font-size: inherit;
35 | padding: 0.4em;
36 | margin: 0 0 0.5em 0;
37 | box-sizing: border-box;
38 | border: 1px solid #ccc;
39 | border-radius: 2px;
40 | }
41 |
42 | input:disabled {
43 | color: #ccc;
44 | }
45 |
46 | input[type="range"] {
47 | height: 0;
48 | }
49 |
50 | button {
51 | background-color: #f4f4f4;
52 | outline: none;
53 | }
54 |
55 | button:active {
56 | background-color: #ddd;
57 | }
58 |
59 | button:focus {
60 | border-color: #666;
61 | }
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Svelte app
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/App.svelte:
--------------------------------------------------------------------------------
1 |
7 |
8 |
13 |
14 | Hello {name}!
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/common/helpers.ts:
--------------------------------------------------------------------------------
1 | export const toUpper = (value:string) : string => value.toUpperCase();
2 |
--------------------------------------------------------------------------------
/src/components/button/Button.svelte:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
14 |
15 |
27 |
--------------------------------------------------------------------------------
/src/components/button/Button2.scss:
--------------------------------------------------------------------------------
1 | @import '~@styles/defaults';
2 |
3 | button.primary {
4 | background-color: $primary-colour1;
5 | color: $lightest;
6 | }
7 |
--------------------------------------------------------------------------------
/src/components/button/Button2.svelte:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
20 |
--------------------------------------------------------------------------------
/src/components/button/ButtonData.ts:
--------------------------------------------------------------------------------
1 | import {toUpper} from "@common/helpers";
2 |
3 |
4 | export let label : string = toUpper('World');
5 |
--------------------------------------------------------------------------------
/src/main.ts:
--------------------------------------------------------------------------------
1 | import App from './App.svelte';
2 |
3 | const app = new App({
4 | target: document.body,
5 | props: {
6 | name: 'world'
7 | }
8 | });
9 |
10 | declare global {
11 | interface Window { app: any; }
12 | }
13 | window.app = app;
14 | export default app;
15 |
--------------------------------------------------------------------------------
/src/styles/defaults.scss:
--------------------------------------------------------------------------------
1 | /* You can add global styles to this file, and also import other style files */
2 | @import "variables";
3 | @import "icons";
4 |
5 | button {
6 | background: $primary-colour1;
7 | color: $lightest;
8 | box-shadow: 0 3px 1px -2px rgba(0,0,0,.2), 0 2px 2px 0 rgba(0,0,0,.14), 0 1px 5px 0 rgba(0,0,0,.12);
9 | box-sizing: border-box;
10 | position: relative;
11 | -webkit-user-select: none;
12 | -moz-user-select: none;
13 | -ms-user-select: none;
14 | user-select: none;
15 | cursor: pointer;
16 | outline: 0;
17 | border: none;
18 | -webkit-tap-highlight-color: transparent;
19 | display: inline-block;
20 | white-space: nowrap;
21 | text-decoration: none;
22 | vertical-align: baseline;
23 | text-align: center;
24 | margin: 0;
25 | min-width: 64px;
26 | line-height: 36px;
27 | padding: 0 0.25rem;
28 | border-radius: 4px;
29 | overflow: visible;
30 | transform: translate3d(0,0,0);
31 | transition: background .4s cubic-bezier(.25,.8,.25,1),box-shadow 280ms cubic-bezier(.4,0,.2,1);
32 | }
33 |
34 | button:hover {
35 | transition: background .4s cubic-bezier(.25,.8,.25,1),box-shadow 280ms cubic-bezier(.4,0,.2,1);
36 | background: lighten($primary-colour1, 15%);
37 | }
38 |
--------------------------------------------------------------------------------
/src/styles/icons.scss:
--------------------------------------------------------------------------------
1 | // setup font awesome - must be before imports
2 | $fa-font-path: "~@fortawesome/fontawesome-free/webfonts";
3 |
4 | @import '~@fortawesome/fontawesome-free/scss/fontawesome';
5 | @import "~@fortawesome/fontawesome-free/scss/solid";
6 | @import "~@fortawesome/fontawesome-free/scss/regular";
7 | @import "~@fortawesome/fontawesome-free/scss/brands";
8 |
9 |
10 | .icon {
11 | &.ok:after {
12 | @extend %fa-icon;
13 | @extend .fas;
14 | content: fa-content($fa-var-check);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/styles/variables.scss:
--------------------------------------------------------------------------------
1 | //Global SASS variables
2 | $lightest: #fff;
3 | $darkest: #000;
4 |
5 | $primary-colour1: #296ac8;
6 | $primary-colour2: #ff3807;
7 |
--------------------------------------------------------------------------------
/stories/button.stories.ts:
--------------------------------------------------------------------------------
1 | import { action } from '@storybook/addon-actions';
2 |
3 | import Button from '../src/components/button/Button.svelte';
4 |
5 | export default {
6 | title: 'Button',
7 | };
8 |
9 | export const withSassStyleTag = () => ({
10 | Component: Button,
11 | props: { text: 'Hello' },
12 | on: { click: action('clicked') },
13 | });
14 |
--------------------------------------------------------------------------------
/stories/button2.stories.ts:
--------------------------------------------------------------------------------
1 | import { action } from '@storybook/addon-actions';
2 |
3 | import Button2 from '@src/components/button/Button2.svelte';
4 |
5 | export default {
6 | title: 'Button2',
7 | };
8 |
9 |
10 | export const withSassSource = () => ({
11 | Component: Button2,
12 | props: { text: 'Hello Button2' },
13 | on: { click: action('clicked') },
14 | });
15 |
--------------------------------------------------------------------------------
/svelte.config.js:
--------------------------------------------------------------------------------
1 | const {aliases, scssAliases} = require("./webpack.parts");
2 | const magicImporter = require('node-sass-magic-importer');
3 | const sveltePreprocess = require('svelte-preprocess');
4 |
5 | module.exports = {
6 | preprocess: sveltePreprocess({
7 | scss: {
8 | importer: [
9 | //scssAliases(aliases),
10 | magicImporter()
11 | ],
12 | }
13 | }),
14 | };
15 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "extendedDiagnostics": true,
4 | "outDir": "build/lib",
5 | "module": "es6",
6 | "target": "es6",
7 | "lib": ["es5", "es6", "es7", "es2017", "dom"],
8 | "sourceMap": true,
9 | "allowJs": false,
10 | "types": ["@pyoner/svelte-types"],
11 | "moduleResolution": "node",
12 | "rootDirs": ["src", "stories"],
13 | "baseUrl": "src",
14 | "paths": {
15 | "@styles/*": ["styles/*"],
16 | "@common/*": ["common/*"]
17 | },
18 | "forceConsistentCasingInFileNames": true,
19 | "noImplicitReturns": true,
20 | "noImplicitThis": true,
21 | "noImplicitAny": false,
22 | "strict": true,
23 | "strictNullChecks": true,
24 | "suppressImplicitAnyIndexErrors": true,
25 | "noUnusedLocals": false,
26 | "allowSyntheticDefaultImports": true,
27 | "esModuleInterop": true,
28 | "experimentalDecorators": true,
29 | "emitDecoratorMetadata": true
30 | },
31 | "awesomeTypescriptLoaderOptions": {
32 | "useBabel": true,
33 | "babelCore": "@babel/core"
34 | },
35 | "include": ["src/**/*"],
36 | "exclude": ["node_modules", "build"]
37 | }
38 |
--------------------------------------------------------------------------------
/webpack.common.js:
--------------------------------------------------------------------------------
1 | const {aliases, scssAliases, onwarn} = require( "./webpack.parts");
2 |
3 | const MiniCssExtractPlugin = require('mini-css-extract-plugin');
4 | const {CheckerPlugin} = require('awesome-typescript-loader');
5 | const CopyPlugin = require('copy-webpack-plugin');
6 | const {CleanWebpackPlugin} = require('clean-webpack-plugin');
7 | const path = require('path');
8 | const magicImporter = require('node-sass-magic-importer');
9 |
10 | module.exports = {
11 | entry: {
12 | bundle: ['./src/main.ts']
13 | },
14 | resolve: {
15 | alias: aliases,
16 | extensions: ['.mjs', '.ts', '.tsx', '.js', '.svelte', 'scss', 'css'],
17 | mainFields: ['svelte', 'browser', 'module', 'main'],
18 | modules: [path.resolve(__dirname, 'src'), 'node_modules']
19 | },
20 | output: {
21 | path: path.resolve(__dirname, 'build'),
22 | filename: '[name].js',
23 | chunkFilename: '[name].[id].js'
24 | },
25 | module: {
26 | rules: [
27 | {
28 | test: /\.(ts|tsx)$/,
29 | use: [{loader: require.resolve('awesome-typescript-loader')}],
30 | },
31 | {
32 | test: /\.svelte$/,
33 | use: {
34 | loader: 'svelte-loader',
35 | options: {
36 | emitCss: true,
37 | hotReload: true,
38 | onwarn: onwarn,
39 | preprocess: require('svelte-preprocess')({
40 | scss: {
41 | importer: [
42 | scssAliases(aliases),
43 | //magicImporter()
44 | ],
45 | }
46 | })
47 | }
48 | }
49 | },
50 | {
51 | test: /\.(svg|ico|jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|cur|ani|pdf)(\?.*)?$/,
52 | loader: 'file-loader',
53 | },
54 | /*Style rules are customised in separate dev/prod configs*/
55 | ]
56 | },
57 | plugins: [
58 | new CleanWebpackPlugin(),
59 | new MiniCssExtractPlugin({
60 | filename: '[name].css'
61 | }),
62 | new CheckerPlugin(),
63 | new CopyPlugin([
64 | {from: 'public'}
65 | ])
66 | ]
67 | };
68 |
--------------------------------------------------------------------------------
/webpack.dev.js:
--------------------------------------------------------------------------------
1 | const merge = require('webpack-merge');
2 | const common = require('./webpack.common.js');
3 | const magicImporter = require('node-sass-magic-importer');
4 |
5 | /**
6 | merge.smart replaces matches
7 | You can debug the output using
8 | console.dir(config, { depth: null });
9 | ref: https://github.com/survivejs/webpack-merge
10 | */
11 |
12 | module.exports = merge.smart(common, {
13 | mode: 'development',
14 | devtool: 'inline-source-map',
15 | module: {
16 | rules: [
17 | {
18 | test: /\.(scss|sass|css)$/,
19 | use: [
20 | /**
21 | * MiniCssExtractPlugin doesn't support HMR.
22 | * For developing, use 'style-loader' instead.
23 | * */
24 | 'style-loader',
25 | { loader: 'css-loader', options: { sourceMap: true } },
26 | {
27 | loader: 'sass-loader',
28 | options: {
29 | sassOptions: {
30 | importer: magicImporter()
31 | }
32 | }
33 | }
34 | ]
35 | }
36 | ]
37 | },
38 | devServer: {
39 | contentBase: './build',
40 | port: 4000
41 | },
42 | });
43 |
--------------------------------------------------------------------------------
/webpack.parts.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | /**
4 | * Disables some sass warnings that are not really warnings
5 | */
6 | const onwarn = (warning, onwarn) => warning.code === 'css-unused-selector' || onwarn(warning);
7 |
8 | /**
9 | * Custom Sass Importer to enable the use of aliases in sass.
10 | * This will fall back to node_modules if the path starts with ~ and can not be matched to an alias
11 | */
12 | const scssAliases = aliases => {
13 | return url => {
14 | // console.log('attempting to resolve: '+ url);
15 | // sass-loader normally requires you to add a ~ character to the start of your aliases
16 | if (url.startsWith("~")) {
17 | // we want to remove the ~ character before comparing the url to an alias
18 | this.url = url.slice(1);
19 | for (const [alias, aliasPath] of Object.entries(aliases)) {
20 | if (this.url.indexOf(alias) === 0) {
21 | const filePath = path.resolve(this.url.replace(alias, aliasPath));
22 | // console.log('found alias: '+ alias + '; at ' + filePath);
23 | return {
24 | file: filePath,
25 | };
26 | }
27 | }
28 | //If there was nothing found fall back to node_modules
29 | const filePath = path.resolve(process.cwd(), "node_modules", this.url);
30 | // console.log('Attempting to resolve', filePath);
31 | //if we can't find anything fall back to node_modules
32 | return {
33 | file: filePath
34 | };
35 | }
36 | // console.log('could not match: ' + url);
37 | //if there is no match return null to allow other importers a chance to resolve.
38 | return null;
39 | };
40 | };
41 |
42 | /**
43 | * Aliases used during import, shared between webpack and sass-loader
44 | */
45 | const aliases = {
46 | //TODO: Look at a way to share tsconfig.json paths and these aliases
47 | svelte: path.resolve('node_modules', 'svelte'),
48 | '@src': path.resolve(__dirname, 'src/'),
49 | '@styles': path.resolve(__dirname, 'src/styles/'),
50 | '@common': path.resolve(__dirname, 'src/common/'),
51 | };
52 |
53 |
54 | module.exports = { scssAliases, aliases, onwarn };
55 |
--------------------------------------------------------------------------------
/webpack.prod.js:
--------------------------------------------------------------------------------
1 | const {aliases, scssAliases, onwarn} = require("./webpack.parts");
2 | const merge = require('webpack-merge');
3 | const common = require('./webpack.common.js');
4 | const MiniCssExtractPlugin = require('mini-css-extract-plugin');
5 | const magicImporter = require('node-sass-magic-importer');
6 |
7 | /**
8 | merge.smart replaces matches
9 | You can debug the output using
10 | console.dir(config, { depth: null });
11 | ref: https://github.com/survivejs/webpack-merge
12 | */
13 | let config = merge.smart(common, {
14 | mode: 'production',
15 | module: {
16 | rules: [
17 | {
18 | test: /\.svelte$/,
19 | use: {
20 | loader: 'svelte-loader',
21 | options: {
22 | emitCss: true,
23 | hotReload: false,
24 | onwarn: onwarn,
25 | preprocess: require('svelte-preprocess')({
26 | scss: {
27 | importer: [
28 | // scssAliases(aliases),
29 | magicImporter()
30 | ],
31 | }
32 | })
33 | }
34 | }
35 | },
36 | {
37 | test: /\.(scss|sass|css)$/,
38 | use: [
39 | /**
40 | * MiniCssExtractPlugin doesn't support HMR.
41 | * For developing, use 'style-loader' instead.
42 | * */
43 | MiniCssExtractPlugin.loader,
44 | { loader: 'css-loader', options: { sourceMap: true } },
45 | {
46 | loader: 'sass-loader',
47 | options: {
48 | sassOptions: {
49 | importer: magicImporter()
50 | }
51 | }
52 | }
53 | ]
54 | }
55 | ]
56 | },
57 | });
58 | //console.dir(config, { depth: null });
59 | module.exports = config;
60 |
--------------------------------------------------------------------------------