CSS / SCSS 모듈을 가져올 수 없습니다. TypeScript는 "모듈을 찾을 수 없습니다"라고 말합니다.


82

CSS 모듈에서 테마를 가져 오려고하는데 TypeScript에서 "모듈을 찾을 수 없음"오류가 발생하고 테마가 런타임에 적용되지 않습니다. 내 Webpack 구성에 문제가 있다고 생각하지만 문제가 어디에 있는지 잘 모르겠습니다.

다음 도구를 사용하고 있습니다.

"typescript": "^2.0.3"
"webpack": "2.1.0-beta.25"
"webpack-dev-server": "^2.1.0-beta.9"
"react": "^15.4.0-rc.4"
"react-toolbox": "^1.2.3"
"node-sass": "^3.10.1"
"style-loader": "^0.13.1"
"css-loader": "^0.25.0"
"sass-loader": "^4.0.2"
"sass-lint": "^1.9.1"
"sasslint-webpack-plugin": "^1.0.4"

여기 나의 webpack.config.js

var path = require('path');
var webpack = require('webpack');
var sassLintPlugin = require('sasslint-webpack-plugin');

module.exports = {
  entry: [
    'webpack-dev-server/client?http://localhost:8080',
    'webpack/hot/dev-server',
    './src/index.tsx',
  ],
  output: {
    path: path.resolve(__dirname, 'dist'),
    publicPath: 'http://localhost:8080/',
    filename: 'dist/bundle.js',
  },
  devtool: 'source-map',
  resolve: {
    extensions: ['.webpack.js', '.web.js', '.ts', '.tsx', '.js'],
  },
  module: {
    rules: [{
      test: /\.js$/,
      loader: 'source-map-loader',
      exclude: /node_modules/,
      enforce: 'pre',
    }, {
      test: /\.tsx?$/,
      loader: 'tslint-loader',
      exclude: /node_modules/,
      enforce: 'pre',
    }, {
      test: /\.tsx?$/,
      loaders: [
        'react-hot-loader/webpack',
        'awesome-typescript-loader',
      ],
      exclude: /node_modules/,
    }, {
      test: /\.scss$/,
      loaders: ['style', 'css', 'sass']
    }, {
      test: /\.css$/,
      loaders: ['style', 'css']
    }],
  },
  externals: {
    'react': 'React',
    'react-dom': 'ReactDOM'
  },
  plugins: [
    new sassLintPlugin({
      glob: 'src/**/*.s?(a|c)ss',
      ignoreFiles: ['src/normalize.scss'],
      failOnWarning: false, // Do it.
    }),
    new webpack.HotModuleReplacementPlugin(),
  ],
  devServer: {
    contentBase: './'
  },
};

내가 App.tsx나는 수입을 시도하고 여기서

import * as React from 'react';

import { AppBar } from 'react-toolbox';
import appBarTheme from 'react-toolbox/components/app_bar/theme.scss'
// local ./theme.scss stylesheets aren't found either 

interface IAppStateProps {
  // No props yet
}

interface IAppDispatchProps {
  // No state yet
}

class App extends React.Component<IAppStateProps & IAppDispatchProps, any> {

  constructor(props: IAppStateProps & IAppDispatchProps) {
    super(props);
  }

  public render() {
    return (

        <div className='wrapper'>
          <AppBar title='My App Bar' theme={appBarTheme}>
          </AppBar>
        </div>

    );
  }
}

export default App;

typesafe 스타일 시트 모듈 가져 오기를 사용하려면 또 무엇이 필요합니까?

답변:


120

타이프 라이터가 아닌 다른 파일이 있다는 것을 모르는 .ts또는 .tsx가져 오기가 알 수없는 파일 접미사가있는 경우 때문에 오류가 발생합니다.

다른 유형의 파일을 가져올 수있는 웹팩 구성이있는 경우 TypeScript 컴파일러에 이러한 파일이 있음을 알려야합니다. 그렇게하려면 피팅 이름으로 모듈을 선언하는 선언 파일을 추가하십시오.

선언 할 모듈의 내용은 파일 유형에 사용되는 웹팩 로더에 따라 다릅니다. sass-loadercss-loaderstyle-loader를*.scss 통해 파일을 파이프하는 웹팩 구성 에서 가져온 모듈에는 내용이 없으며 올바른 모듈 선언은 다음과 같습니다.

// declaration.d.ts
declare module '*.scss';

로더가 css-modules에 대해 구성된 경우 다음과 같이 선언을 확장하십시오.

// declaration.d.ts
declare module '*.scss' {
    const content: {[className: string]: string};
    export default content;
}

1
저에게 효과가 없었습니다. 최근에 변경된 사항이 있습니다. stackoverflow.com/questions/56563243/…
Kay

45

다음은 나를 위해 작동하는 완전한 구성입니다.

TypeScript + WebPack + Sass

webpack.config.js

module.exports = {
  //mode: "production", 
    mode: "development", devtool: "inline-source-map",

    entry: [ "./src/app.tsx"/*main*/ ], 
    output: {
        filename: "./bundle.js"  // in /dist
    },
    resolve: {
        // Add `.ts` and `.tsx` as a resolvable extension.
        extensions: [".ts", ".tsx", ".js", ".css", ".scss"]
    },
    module: {
        rules: [

            { test: /\.tsx?$/, loader: "ts-loader" }, 

            { test: /\.scss$/, use: [ 
                { loader: "style-loader" },  // to inject the result into the DOM as a style block
                { loader: "css-modules-typescript-loader"},  // to generate a .d.ts module next to the .scss file (also requires a declaration.d.ts with "declare modules '*.scss';" in it to tell TypeScript that "import styles from './styles.scss';" means to load the module "./styles.scss.d.td")
                { loader: "css-loader", options: { modules: true } },  // to convert the resulting CSS to Javascript to be bundled (modules:true to rename CSS classes in output to cryptic identifiers, except if wrapped in a :global(...) pseudo class)
                { loader: "sass-loader" },  // to convert SASS to CSS
                // NOTE: The first build after adding/removing/renaming CSS classes fails, since the newly generated .d.ts typescript module is picked up only later
            ] }, 

        ]
    }
}; 

또한 declarations.d.ts프로젝트에 다음을 입력하십시오.

// We need to tell TypeScript that when we write "import styles from './styles.scss' we mean to load a module (to look for a './styles.scss.d.ts'). 
declare module '*.scss'; 

그리고 당신 package.json의 개발 의존성 에이 모든 것이 필요할 것입니다 .

  "devDependencies": {
    "@types/node-sass": "^4.11.0",
    "node-sass": "^4.12.0",
    "css-loader": "^1.0.0",
    "css-modules-typescript-loader": "^2.0.1",
    "sass-loader": "^7.1.0",
    "style-loader": "^0.23.1",
    "ts-loader": "^5.3.3",
    "typescript": "^3.4.4",
    "webpack": "^4.30.0",
    "webpack-cli": "^3.3.0"
  }

그런 mystyle.d.ts다음 mystyle.scss정의한 CSS 클래스가 포함 된 옆에 Typescript 모듈로 가져 와서 다음과 같이 사용할 수 있습니다.

import * as styles from './mystyles.scss'; 

const foo = <div className={styles.myClass}>FOO</div>; 

CSS는 자동으로로드되고 ( styleDOM에 요소로 삽입 됨 ) .scss의 CSS 클래스 대신 암호화 식별자를 포함하여 페이지에서 스타일을 분리합니다 (를 사용하지 않는 경우 :global(.a-global-class) { ... }).

있습니다 첫 번째 컴파일이 실패 가져온 mystyles.d.ts가 이전 버전뿐 아니라 컴파일시 생성 된 새 버전이기 때문에 당신이 CSS 클래스를 추가하거나 제거하거나 이름을 바꿀 때마다. 다시 컴파일하십시오.

즐겨.


"참고 : 새로 생성 된 .d.ts typescript 모듈이 나중에 선택되기 때문에 CSS 클래스를 추가 / 제거 / 이름 변경 한 후 첫 번째 빌드가 실패합니다."-해당 부분을 해결하는 방법은 무엇입니까?
Jon Lauridsen

3
@JonLauridsen webpack.config.js에서 규칙 배열의 맨 아래 (끝)에 ts-loader를 설정하여 해결할 수 있습니다. 따라서 ts-loader는 이전에 생성 될 모든 컴파일 원인으로 올바른 * .scss.d.ts 파일을 선택합니다.
Yan Pak

1
@YanPak 감사 합니다. ts-loader를 스타일 로더 아래로 이동하면서 global.d.tssrc디렉토리에 a 를 추가하면 문제 가 해결되었습니다.
lux

4

tsconfig.json 경로 설정을 사용하는 경우주의

이러한 솔루션을 tsconfig 경로와 함께 사용하여 가져 오기를 단축하는 경우 추가 구성이 필요합니다.

다음과 같은 tsconfig 경로를 사용하는 경우 :

{
  "compilerOptions": {
    "paths": {
      "style/*": [ "src/style/*" ],
    }
  }
}

따라서 다음을 수행 할 수 있습니다.

import { header } from 'style/ui.scss';

그런 다음 다음 과 같이 웹팩에 모듈 해석 구성을 추가해야합니다 .

module.exports = {
  ...
  resolve: {
    ...
    alias: {
      style: path.resolve(__dirname, 'src', 'style')
    }
  }
}

설정에 따라 경로가 설정되었는지 확인하십시오.

이것은 새로운 가져 오기 경로가 실제로 모듈이라고 생각하기 때문에 webpack이 어디를 찾아야하는지 알 수 있도록하므로 기본값은 node_modules 디렉토리입니다. 이 구성을 사용하면 어디를보고 찾을 지 알고 빌드가 작동합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.